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

Side by Side Diff: src/spaces.cc

Issue 11118018: Enable --verify-heap in release mode (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 2 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/store-buffer.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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 490
491 MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size, 491 MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t body_size,
492 Executability executable, 492 Executability executable,
493 Space* owner) { 493 Space* owner) {
494 size_t chunk_size; 494 size_t chunk_size;
495 Heap* heap = isolate_->heap(); 495 Heap* heap = isolate_->heap();
496 Address base = NULL; 496 Address base = NULL;
497 VirtualMemory reservation; 497 VirtualMemory reservation;
498 Address area_start = NULL; 498 Address area_start = NULL;
499 Address area_end = NULL; 499 Address area_end = NULL;
500
500 if (executable == EXECUTABLE) { 501 if (executable == EXECUTABLE) {
501 chunk_size = RoundUp(CodePageAreaStartOffset() + body_size, 502 chunk_size = RoundUp(CodePageAreaStartOffset() + body_size,
502 OS::CommitPageSize()) + CodePageGuardSize(); 503 OS::CommitPageSize()) + CodePageGuardSize();
503 504
504 // Check executable memory limit. 505 // Check executable memory limit.
505 if (size_executable_ + chunk_size > capacity_executable_) { 506 if (size_executable_ + chunk_size > capacity_executable_) {
506 LOG(isolate_, 507 LOG(isolate_,
507 StringEvent("MemoryAllocator::AllocateRawMemory", 508 StringEvent("MemoryAllocator::AllocateRawMemory",
508 "V8 Executable Allocation capacity exceeded")); 509 "V8 Executable Allocation capacity exceeded"));
509 return NULL; 510 return NULL;
(...skipping 12 matching lines...) Expand all
522 } else { 523 } else {
523 base = AllocateAlignedMemory(chunk_size, 524 base = AllocateAlignedMemory(chunk_size,
524 MemoryChunk::kAlignment, 525 MemoryChunk::kAlignment,
525 executable, 526 executable,
526 &reservation); 527 &reservation);
527 if (base == NULL) return NULL; 528 if (base == NULL) return NULL;
528 // Update executable memory size. 529 // Update executable memory size.
529 size_executable_ += reservation.size(); 530 size_executable_ += reservation.size();
530 } 531 }
531 532
532 #ifdef DEBUG 533 if (Heap::ShouldZapGarbage()) {
533 ZapBlock(base, CodePageGuardStartOffset()); 534 ZapBlock(base, CodePageGuardStartOffset());
534 ZapBlock(base + CodePageAreaStartOffset(), body_size); 535 ZapBlock(base + CodePageAreaStartOffset(), body_size);
535 #endif 536 }
537
536 area_start = base + CodePageAreaStartOffset(); 538 area_start = base + CodePageAreaStartOffset();
537 area_end = area_start + body_size; 539 area_end = area_start + body_size;
538 } else { 540 } else {
539 chunk_size = MemoryChunk::kObjectStartOffset + body_size; 541 chunk_size = MemoryChunk::kObjectStartOffset + body_size;
540 base = AllocateAlignedMemory(chunk_size, 542 base = AllocateAlignedMemory(chunk_size,
541 MemoryChunk::kAlignment, 543 MemoryChunk::kAlignment,
542 executable, 544 executable,
543 &reservation); 545 &reservation);
544 546
545 if (base == NULL) return NULL; 547 if (base == NULL) return NULL;
546 548
547 #ifdef DEBUG 549 if (Heap::ShouldZapGarbage()) {
548 ZapBlock(base, chunk_size); 550 ZapBlock(base, chunk_size);
549 #endif 551 }
550 552
551 area_start = base + Page::kObjectStartOffset; 553 area_start = base + Page::kObjectStartOffset;
552 area_end = base + chunk_size; 554 area_end = base + chunk_size;
553 } 555 }
554 556
555 isolate_->counters()->memory_allocated()-> 557 isolate_->counters()->memory_allocated()->
556 Increment(static_cast<int>(chunk_size)); 558 Increment(static_cast<int>(chunk_size));
557 559
558 LOG(isolate_, NewEvent("MemoryChunk", base, chunk_size)); 560 LOG(isolate_, NewEvent("MemoryChunk", base, chunk_size));
559 if (owner != NULL) { 561 if (owner != NULL) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 chunk->size(), 617 chunk->size(),
616 chunk->executable()); 618 chunk->executable());
617 } 619 }
618 } 620 }
619 621
620 622
621 bool MemoryAllocator::CommitBlock(Address start, 623 bool MemoryAllocator::CommitBlock(Address start,
622 size_t size, 624 size_t size,
623 Executability executable) { 625 Executability executable) {
624 if (!VirtualMemory::CommitRegion(start, size, executable)) return false; 626 if (!VirtualMemory::CommitRegion(start, size, executable)) return false;
625 #ifdef DEBUG 627
626 ZapBlock(start, size); 628 if (Heap::ShouldZapGarbage()) {
627 #endif 629 ZapBlock(start, size);
630 }
631
628 isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size)); 632 isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size));
629 return true; 633 return true;
630 } 634 }
631 635
632 636
633 bool MemoryAllocator::UncommitBlock(Address start, size_t size) { 637 bool MemoryAllocator::UncommitBlock(Address start, size_t size) {
634 if (!VirtualMemory::UncommitRegion(start, size)) return false; 638 if (!VirtualMemory::UncommitRegion(start, size)) return false;
635 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size)); 639 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size));
636 return true; 640 return true;
637 } 641 }
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 } 982 }
979 } 983 }
980 heap()->FreeQueuedChunks(); 984 heap()->FreeQueuedChunks();
981 } 985 }
982 986
983 987
984 #ifdef DEBUG 988 #ifdef DEBUG
985 void PagedSpace::Print() { } 989 void PagedSpace::Print() { }
986 #endif 990 #endif
987 991
988 992 #ifdef VERIFY_HEAP
989 #ifdef DEBUG
990 void PagedSpace::Verify(ObjectVisitor* visitor) { 993 void PagedSpace::Verify(ObjectVisitor* visitor) {
991 // We can only iterate over the pages if they were swept precisely. 994 // We can only iterate over the pages if they were swept precisely.
992 if (was_swept_conservatively_) return; 995 if (was_swept_conservatively_) return;
993 996
994 bool allocation_pointer_found_in_space = 997 bool allocation_pointer_found_in_space =
995 (allocation_info_.top == allocation_info_.limit); 998 (allocation_info_.top == allocation_info_.limit);
996 PageIterator page_iterator(this); 999 PageIterator page_iterator(this);
997 while (page_iterator.has_next()) { 1000 while (page_iterator.has_next()) {
998 Page* page = page_iterator.next(); 1001 Page* page = page_iterator.next();
999 ASSERT(page->owner() == this); 1002 CHECK(page->owner() == this);
1000 if (page == Page::FromAllocationTop(allocation_info_.top)) { 1003 if (page == Page::FromAllocationTop(allocation_info_.top)) {
1001 allocation_pointer_found_in_space = true; 1004 allocation_pointer_found_in_space = true;
1002 } 1005 }
1003 ASSERT(page->WasSweptPrecisely()); 1006 CHECK(page->WasSweptPrecisely());
1004 HeapObjectIterator it(page, NULL); 1007 HeapObjectIterator it(page, NULL);
1005 Address end_of_previous_object = page->area_start(); 1008 Address end_of_previous_object = page->area_start();
1006 Address top = page->area_end(); 1009 Address top = page->area_end();
1007 int black_size = 0; 1010 int black_size = 0;
1008 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { 1011 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
1009 ASSERT(end_of_previous_object <= object->address()); 1012 CHECK(end_of_previous_object <= object->address());
1010 1013
1011 // The first word should be a map, and we expect all map pointers to 1014 // The first word should be a map, and we expect all map pointers to
1012 // be in map space. 1015 // be in map space.
1013 Map* map = object->map(); 1016 Map* map = object->map();
1014 ASSERT(map->IsMap()); 1017 CHECK(map->IsMap());
1015 ASSERT(heap()->map_space()->Contains(map)); 1018 CHECK(heap()->map_space()->Contains(map));
1016 1019
1017 // Perform space-specific object verification. 1020 // Perform space-specific object verification.
1018 VerifyObject(object); 1021 VerifyObject(object);
1019 1022
1020 // The object itself should look OK. 1023 // The object itself should look OK.
1021 object->Verify(); 1024 object->Verify();
1022 1025
1023 // All the interior pointers should be contained in the heap. 1026 // All the interior pointers should be contained in the heap.
1024 int size = object->Size(); 1027 int size = object->Size();
1025 object->IterateBody(map->instance_type(), size, visitor); 1028 object->IterateBody(map->instance_type(), size, visitor);
1026 if (Marking::IsBlack(Marking::MarkBitFrom(object))) { 1029 if (Marking::IsBlack(Marking::MarkBitFrom(object))) {
1027 black_size += size; 1030 black_size += size;
1028 } 1031 }
1029 1032
1030 ASSERT(object->address() + size <= top); 1033 CHECK(object->address() + size <= top);
1031 end_of_previous_object = object->address() + size; 1034 end_of_previous_object = object->address() + size;
1032 } 1035 }
1033 ASSERT_LE(black_size, page->LiveBytes()); 1036 CHECK_LE(black_size, page->LiveBytes());
1034 } 1037 }
1035 ASSERT(allocation_pointer_found_in_space); 1038 CHECK(allocation_pointer_found_in_space);
1036 } 1039 }
1037 #endif 1040 #endif // VERIFY_HEAP
1038
1039 1041
1040 // ----------------------------------------------------------------------------- 1042 // -----------------------------------------------------------------------------
1041 // NewSpace implementation 1043 // NewSpace implementation
1042 1044
1043 1045
1044 bool NewSpace::SetUp(int reserved_semispace_capacity, 1046 bool NewSpace::SetUp(int reserved_semispace_capacity,
1045 int maximum_semispace_capacity) { 1047 int maximum_semispace_capacity) {
1046 // Set up new space based on the preallocated memory block defined by 1048 // Set up new space based on the preallocated memory block defined by
1047 // start and size. The provided space is divided into two semi-spaces. 1049 // start and size. The provided space is divided into two semi-spaces.
1048 // To support fast containment testing in the new space, the size of 1050 // To support fast containment testing in the new space, the size of
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 heap()->incremental_marking()->Step( 1254 heap()->incremental_marking()->Step(
1253 bytes_allocated, IncrementalMarking::GC_VIA_STACK_GUARD); 1255 bytes_allocated, IncrementalMarking::GC_VIA_STACK_GUARD);
1254 top_on_previous_step_ = to_space_.page_low(); 1256 top_on_previous_step_ = to_space_.page_low();
1255 return AllocateRaw(size_in_bytes); 1257 return AllocateRaw(size_in_bytes);
1256 } else { 1258 } else {
1257 return Failure::RetryAfterGC(); 1259 return Failure::RetryAfterGC();
1258 } 1260 }
1259 } 1261 }
1260 1262
1261 1263
1262 #ifdef DEBUG 1264 #ifdef VERIFY_HEAP
1263 // We do not use the SemiSpaceIterator because verification doesn't assume 1265 // We do not use the SemiSpaceIterator because verification doesn't assume
1264 // that it works (it depends on the invariants we are checking). 1266 // that it works (it depends on the invariants we are checking).
1265 void NewSpace::Verify() { 1267 void NewSpace::Verify() {
1266 // The allocation pointer should be in the space or at the very end. 1268 // The allocation pointer should be in the space or at the very end.
1267 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); 1269 ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
1268 1270
1269 // There should be objects packed in from the low address up to the 1271 // There should be objects packed in from the low address up to the
1270 // allocation pointer. 1272 // allocation pointer.
1271 Address current = to_space_.first_page()->area_start(); 1273 Address current = to_space_.first_page()->area_start();
1272 CHECK_EQ(current, to_space_.space_start()); 1274 CHECK_EQ(current, to_space_.space_start());
(...skipping 28 matching lines...) Expand all
1301 } else { 1303 } else {
1302 // At end of page, switch to next page. 1304 // At end of page, switch to next page.
1303 NewSpacePage* page = NewSpacePage::FromLimit(current)->next_page(); 1305 NewSpacePage* page = NewSpacePage::FromLimit(current)->next_page();
1304 // Next page should be valid. 1306 // Next page should be valid.
1305 CHECK(!page->is_anchor()); 1307 CHECK(!page->is_anchor());
1306 current = page->area_start(); 1308 current = page->area_start();
1307 } 1309 }
1308 } 1310 }
1309 1311
1310 // Check semi-spaces. 1312 // Check semi-spaces.
1311 ASSERT_EQ(from_space_.id(), kFromSpace); 1313 CHECK_EQ(from_space_.id(), kFromSpace);
1312 ASSERT_EQ(to_space_.id(), kToSpace); 1314 CHECK_EQ(to_space_.id(), kToSpace);
1313 from_space_.Verify(); 1315 from_space_.Verify();
1314 to_space_.Verify(); 1316 to_space_.Verify();
1315 } 1317 }
1316 #endif 1318 #endif
1317 1319
1318 // ----------------------------------------------------------------------------- 1320 // -----------------------------------------------------------------------------
1319 // SemiSpace implementation 1321 // SemiSpace implementation
1320 1322
1321 void SemiSpace::SetUp(Address start, 1323 void SemiSpace::SetUp(Address start,
1322 int initial_capacity, 1324 int initial_capacity,
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 // Mark all pages up to the one containing mark. 1520 // Mark all pages up to the one containing mark.
1519 NewSpacePageIterator it(space_start(), mark); 1521 NewSpacePageIterator it(space_start(), mark);
1520 while (it.has_next()) { 1522 while (it.has_next()) {
1521 it.next()->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); 1523 it.next()->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK);
1522 } 1524 }
1523 } 1525 }
1524 1526
1525 1527
1526 #ifdef DEBUG 1528 #ifdef DEBUG
1527 void SemiSpace::Print() { } 1529 void SemiSpace::Print() { }
1530 #endif
1528 1531
1529 1532 #ifdef VERIFY_HEAP
1530 void SemiSpace::Verify() { 1533 void SemiSpace::Verify() {
1531 bool is_from_space = (id_ == kFromSpace); 1534 bool is_from_space = (id_ == kFromSpace);
1532 NewSpacePage* page = anchor_.next_page(); 1535 NewSpacePage* page = anchor_.next_page();
1533 CHECK(anchor_.semi_space() == this); 1536 CHECK(anchor_.semi_space() == this);
1534 while (page != &anchor_) { 1537 while (page != &anchor_) {
1535 CHECK(page->semi_space() == this); 1538 CHECK(page->semi_space() == this);
1536 CHECK(page->InNewSpace()); 1539 CHECK(page->InNewSpace());
1537 CHECK(page->IsFlagSet(is_from_space ? MemoryChunk::IN_FROM_SPACE 1540 CHECK(page->IsFlagSet(is_from_space ? MemoryChunk::IN_FROM_SPACE
1538 : MemoryChunk::IN_TO_SPACE)); 1541 : MemoryChunk::IN_TO_SPACE));
1539 CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE 1542 CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE
1540 : MemoryChunk::IN_FROM_SPACE)); 1543 : MemoryChunk::IN_FROM_SPACE));
1541 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING)); 1544 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING));
1542 if (!is_from_space) { 1545 if (!is_from_space) {
1543 // The pointers-from-here-are-interesting flag isn't updated dynamically 1546 // The pointers-from-here-are-interesting flag isn't updated dynamically
1544 // on from-space pages, so it might be out of sync with the marking state. 1547 // on from-space pages, so it might be out of sync with the marking state.
1545 if (page->heap()->incremental_marking()->IsMarking()) { 1548 if (page->heap()->incremental_marking()->IsMarking()) {
1546 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); 1549 CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING));
1547 } else { 1550 } else {
1548 CHECK(!page->IsFlagSet( 1551 CHECK(!page->IsFlagSet(
1549 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)); 1552 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING));
1550 } 1553 }
1551 // TODO(gc): Check that the live_bytes_count_ field matches the 1554 // TODO(gc): Check that the live_bytes_count_ field matches the
1552 // black marking on the page (if we make it match in new-space). 1555 // black marking on the page (if we make it match in new-space).
1553 } 1556 }
1554 CHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE)); 1557 CHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE));
1555 CHECK(page->prev_page()->next_page() == page); 1558 CHECK(page->prev_page()->next_page() == page);
1556 page = page->next_page(); 1559 page = page->next_page();
1557 } 1560 }
1558 } 1561 }
1562 #endif
1559 1563
1560 1564 #ifdef DEBUG
1561 void SemiSpace::AssertValidRange(Address start, Address end) { 1565 void SemiSpace::AssertValidRange(Address start, Address end) {
1562 // Addresses belong to same semi-space 1566 // Addresses belong to same semi-space
1563 NewSpacePage* page = NewSpacePage::FromLimit(start); 1567 NewSpacePage* page = NewSpacePage::FromLimit(start);
1564 NewSpacePage* end_page = NewSpacePage::FromLimit(end); 1568 NewSpacePage* end_page = NewSpacePage::FromLimit(end);
1565 SemiSpace* space = page->semi_space(); 1569 SemiSpace* space = page->semi_space();
1566 CHECK_EQ(space, end_page->semi_space()); 1570 CHECK_EQ(space, end_page->semi_space());
1567 // Start address is before end address, either on same page, 1571 // Start address is before end address, either on same page,
1568 // or end address is on a later page in the linked list of 1572 // or end address is on a later page in the linked list of
1569 // semi-space pages. 1573 // semi-space pages.
1570 if (page == end_page) { 1574 if (page == end_page) {
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 // collection. 2548 // collection.
2545 accounting_stats_.AllocateBytes(free_list_.available()); 2549 accounting_stats_.AllocateBytes(free_list_.available());
2546 2550
2547 // Clear the free list before a full GC---it will be rebuilt afterward. 2551 // Clear the free list before a full GC---it will be rebuilt afterward.
2548 free_list_.Reset(); 2552 free_list_.Reset();
2549 } 2553 }
2550 2554
2551 2555
2552 // ----------------------------------------------------------------------------- 2556 // -----------------------------------------------------------------------------
2553 // MapSpace implementation 2557 // MapSpace implementation
2558 // TODO(mvstanton): this is weird...the compiler can't make a vtable unless
2559 // there is at least one non-inlined virtual function. I would prefer to hide
2560 // the VerifyObject definition behind VERIFY_HEAP.
2554 2561
2555 #ifdef DEBUG
2556 void MapSpace::VerifyObject(HeapObject* object) { 2562 void MapSpace::VerifyObject(HeapObject* object) {
2557 // The object should be a map or a free-list node. 2563 // The object should be a map or a free-list node.
2558 ASSERT(object->IsMap() || object->IsFreeSpace()); 2564 CHECK(object->IsMap() || object->IsFreeSpace());
2559 } 2565 }
2560 #endif
2561 2566
2562 2567
2563 // ----------------------------------------------------------------------------- 2568 // -----------------------------------------------------------------------------
2564 // GlobalPropertyCellSpace implementation 2569 // GlobalPropertyCellSpace implementation
2570 // TODO(mvstanton): this is weird...the compiler can't make a vtable unless
2571 // there is at least one non-inlined virtual function. I would prefer to hide
2572 // the VerifyObject definition behind VERIFY_HEAP.
2565 2573
2566 #ifdef DEBUG
2567 void CellSpace::VerifyObject(HeapObject* object) { 2574 void CellSpace::VerifyObject(HeapObject* object) {
2568 // The object should be a global object property cell or a free-list node. 2575 // The object should be a global object property cell or a free-list node.
2569 ASSERT(object->IsJSGlobalPropertyCell() || 2576 CHECK(object->IsJSGlobalPropertyCell() ||
2570 object->map() == heap()->two_pointer_filler_map()); 2577 object->map() == heap()->two_pointer_filler_map());
2571 } 2578 }
2572 #endif
2573 2579
2574 2580
2575 // ----------------------------------------------------------------------------- 2581 // -----------------------------------------------------------------------------
2576 // LargeObjectIterator 2582 // LargeObjectIterator
2577 2583
2578 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space) { 2584 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space) {
2579 current_ = space->first_page_; 2585 current_ = space->first_page_;
2580 size_func_ = NULL; 2586 size_func_ = NULL;
2581 } 2587 }
2582 2588
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2672 for (uintptr_t key = base; key <= limit; key++) { 2678 for (uintptr_t key = base; key <= limit; key++) {
2673 HashMap::Entry* entry = chunk_map_.Lookup(reinterpret_cast<void*>(key), 2679 HashMap::Entry* entry = chunk_map_.Lookup(reinterpret_cast<void*>(key),
2674 static_cast<uint32_t>(key), 2680 static_cast<uint32_t>(key),
2675 true); 2681 true);
2676 ASSERT(entry != NULL); 2682 ASSERT(entry != NULL);
2677 entry->value = page; 2683 entry->value = page;
2678 } 2684 }
2679 2685
2680 HeapObject* object = page->GetObject(); 2686 HeapObject* object = page->GetObject();
2681 2687
2682 #ifdef DEBUG 2688 if (Heap::ShouldZapGarbage()) {
2683 // Make the object consistent so the heap can be vefified in OldSpaceStep. 2689 // Make the object consistent so the heap can be verified in OldSpaceStep.
2684 reinterpret_cast<Object**>(object->address())[0] = 2690 // We only need to do this in debug builds or if verify_heap is on.
2685 heap()->fixed_array_map(); 2691 reinterpret_cast<Object**>(object->address())[0] =
2686 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0); 2692 heap()->fixed_array_map();
2687 #endif 2693 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0);
2694 }
2688 2695
2689 heap()->incremental_marking()->OldSpaceStep(object_size); 2696 heap()->incremental_marking()->OldSpaceStep(object_size);
2690 return object; 2697 return object;
2691 } 2698 }
2692 2699
2693 2700
2694 // GC support 2701 // GC support
2695 MaybeObject* LargeObjectSpace::FindObject(Address a) { 2702 MaybeObject* LargeObjectSpace::FindObject(Address a) {
2696 LargePage* page = FindPage(a); 2703 LargePage* page = FindPage(a);
2697 if (page != NULL) { 2704 if (page != NULL) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2776 MemoryChunk* chunk = MemoryChunk::FromAddress(address); 2783 MemoryChunk* chunk = MemoryChunk::FromAddress(address);
2777 2784
2778 bool owned = (chunk->owner() == this); 2785 bool owned = (chunk->owner() == this);
2779 2786
2780 SLOW_ASSERT(!owned || !FindObject(address)->IsFailure()); 2787 SLOW_ASSERT(!owned || !FindObject(address)->IsFailure());
2781 2788
2782 return owned; 2789 return owned;
2783 } 2790 }
2784 2791
2785 2792
2786 #ifdef DEBUG 2793 #ifdef VERIFY_HEAP
2787 // We do not assume that the large object iterator works, because it depends 2794 // We do not assume that the large object iterator works, because it depends
2788 // on the invariants we are checking during verification. 2795 // on the invariants we are checking during verification.
2789 void LargeObjectSpace::Verify() { 2796 void LargeObjectSpace::Verify() {
2790 for (LargePage* chunk = first_page_; 2797 for (LargePage* chunk = first_page_;
2791 chunk != NULL; 2798 chunk != NULL;
2792 chunk = chunk->next_page()) { 2799 chunk = chunk->next_page()) {
2793 // Each chunk contains an object that starts at the large object page's 2800 // Each chunk contains an object that starts at the large object page's
2794 // object area start. 2801 // object area start.
2795 HeapObject* object = chunk->GetObject(); 2802 HeapObject* object = chunk->GetObject();
2796 Page* page = Page::FromAddress(object->address()); 2803 Page* page = Page::FromAddress(object->address());
2797 ASSERT(object->address() == page->area_start()); 2804 CHECK(object->address() == page->area_start());
2798 2805
2799 // The first word should be a map, and we expect all map pointers to be 2806 // The first word should be a map, and we expect all map pointers to be
2800 // in map space. 2807 // in map space.
2801 Map* map = object->map(); 2808 Map* map = object->map();
2802 ASSERT(map->IsMap()); 2809 CHECK(map->IsMap());
2803 ASSERT(heap()->map_space()->Contains(map)); 2810 CHECK(heap()->map_space()->Contains(map));
2804 2811
2805 // We have only code, sequential strings, external strings 2812 // We have only code, sequential strings, external strings
2806 // (sequential strings that have been morphed into external 2813 // (sequential strings that have been morphed into external
2807 // strings), fixed arrays, and byte arrays in large object space. 2814 // strings), fixed arrays, and byte arrays in large object space.
2808 ASSERT(object->IsCode() || object->IsSeqString() || 2815 CHECK(object->IsCode() || object->IsSeqString() ||
2809 object->IsExternalString() || object->IsFixedArray() || 2816 object->IsExternalString() || object->IsFixedArray() ||
2810 object->IsFixedDoubleArray() || object->IsByteArray()); 2817 object->IsFixedDoubleArray() || object->IsByteArray());
2811 2818
2812 // The object itself should look OK. 2819 // The object itself should look OK.
2813 object->Verify(); 2820 object->Verify();
2814 2821
2815 // Byte arrays and strings don't have interior pointers. 2822 // Byte arrays and strings don't have interior pointers.
2816 if (object->IsCode()) { 2823 if (object->IsCode()) {
2817 VerifyPointersVisitor code_visitor; 2824 VerifyPointersVisitor code_visitor;
2818 object->IterateBody(map->instance_type(), 2825 object->IterateBody(map->instance_type(),
2819 object->Size(), 2826 object->Size(),
2820 &code_visitor); 2827 &code_visitor);
2821 } else if (object->IsFixedArray()) { 2828 } else if (object->IsFixedArray()) {
2822 FixedArray* array = FixedArray::cast(object); 2829 FixedArray* array = FixedArray::cast(object);
2823 for (int j = 0; j < array->length(); j++) { 2830 for (int j = 0; j < array->length(); j++) {
2824 Object* element = array->get(j); 2831 Object* element = array->get(j);
2825 if (element->IsHeapObject()) { 2832 if (element->IsHeapObject()) {
2826 HeapObject* element_object = HeapObject::cast(element); 2833 HeapObject* element_object = HeapObject::cast(element);
2827 ASSERT(heap()->Contains(element_object)); 2834 CHECK(heap()->Contains(element_object));
2828 ASSERT(element_object->map()->IsMap()); 2835 CHECK(element_object->map()->IsMap());
2829 } 2836 }
2830 } 2837 }
2831 } 2838 }
2832 } 2839 }
2833 } 2840 }
2841 #endif
2834 2842
2835 2843
2844 #ifdef DEBUG
2836 void LargeObjectSpace::Print() { 2845 void LargeObjectSpace::Print() {
2837 LargeObjectIterator it(this); 2846 LargeObjectIterator it(this);
2838 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 2847 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
2839 obj->Print(); 2848 obj->Print();
2840 } 2849 }
2841 } 2850 }
2842 2851
2843 2852
2844 void LargeObjectSpace::ReportStatistics() { 2853 void LargeObjectSpace::ReportStatistics() {
2845 PrintF(" size: %" V8_PTR_PREFIX "d\n", size_); 2854 PrintF(" size: %" V8_PTR_PREFIX "d\n", size_);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2888 object->ShortPrint(); 2897 object->ShortPrint();
2889 PrintF("\n"); 2898 PrintF("\n");
2890 } 2899 }
2891 printf(" --------------------------------------\n"); 2900 printf(" --------------------------------------\n");
2892 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 2901 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
2893 } 2902 }
2894 2903
2895 #endif // DEBUG 2904 #endif // DEBUG
2896 2905
2897 } } // namespace v8::internal 2906 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/spaces.h ('k') | src/store-buffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698