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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
2554 | 2558 // MVSTANTON: this is weird...the compiler can't make a vtable unless there is |
Michael Starzinger
2012/10/12 10:53:16
If you want to leave that comment in, format it li
mvstanton1
2012/10/12 11:16:27
Done.
| |
2555 #ifdef DEBUG | 2559 // at least one non-inlined virtual function. Of course, no one will call it... |
2560 // #ifdef VERIFY_HEAP | |
2556 void MapSpace::VerifyObject(HeapObject* object) { | 2561 void MapSpace::VerifyObject(HeapObject* object) { |
2557 // The object should be a map or a free-list node. | 2562 // The object should be a map or a free-list node. |
2558 ASSERT(object->IsMap() || object->IsFreeSpace()); | 2563 CHECK(object->IsMap() || object->IsFreeSpace()); |
2559 } | 2564 } |
2560 #endif | 2565 // #endif |
2561 | |
2562 | 2566 |
2563 // ----------------------------------------------------------------------------- | 2567 // ----------------------------------------------------------------------------- |
2564 // GlobalPropertyCellSpace implementation | 2568 // GlobalPropertyCellSpace implementation |
2565 | 2569 // MVSTANTON: same as above |
Michael Starzinger
2012/10/12 10:53:16
Likewise.
mvstanton1
2012/10/12 11:16:27
Done.
| |
2566 #ifdef DEBUG | 2570 // #ifdef VERIFY_HEAP |
2567 void CellSpace::VerifyObject(HeapObject* object) { | 2571 void CellSpace::VerifyObject(HeapObject* object) { |
2568 // The object should be a global object property cell or a free-list node. | 2572 // The object should be a global object property cell or a free-list node. |
2569 ASSERT(object->IsJSGlobalPropertyCell() || | 2573 CHECK(object->IsJSGlobalPropertyCell() || |
2570 object->map() == heap()->two_pointer_filler_map()); | 2574 object->map() == heap()->two_pointer_filler_map()); |
2571 } | 2575 } |
2572 #endif | 2576 // #endif |
2573 | |
2574 | 2577 |
2575 // ----------------------------------------------------------------------------- | 2578 // ----------------------------------------------------------------------------- |
2576 // LargeObjectIterator | 2579 // LargeObjectIterator |
2577 | 2580 |
2578 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space) { | 2581 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space) { |
2579 current_ = space->first_page_; | 2582 current_ = space->first_page_; |
2580 size_func_ = NULL; | 2583 size_func_ = NULL; |
2581 } | 2584 } |
2582 | 2585 |
2583 | 2586 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2672 for (uintptr_t key = base; key <= limit; key++) { | 2675 for (uintptr_t key = base; key <= limit; key++) { |
2673 HashMap::Entry* entry = chunk_map_.Lookup(reinterpret_cast<void*>(key), | 2676 HashMap::Entry* entry = chunk_map_.Lookup(reinterpret_cast<void*>(key), |
2674 static_cast<uint32_t>(key), | 2677 static_cast<uint32_t>(key), |
2675 true); | 2678 true); |
2676 ASSERT(entry != NULL); | 2679 ASSERT(entry != NULL); |
2677 entry->value = page; | 2680 entry->value = page; |
2678 } | 2681 } |
2679 | 2682 |
2680 HeapObject* object = page->GetObject(); | 2683 HeapObject* object = page->GetObject(); |
2681 | 2684 |
2682 #ifdef DEBUG | 2685 if (Heap::ShouldZapGarbage()) { |
2683 // Make the object consistent so the heap can be vefified in OldSpaceStep. | 2686 // Make the object consistent so the heap can be verified in OldSpaceStep. |
2684 reinterpret_cast<Object**>(object->address())[0] = | 2687 // We only need to do this in debug builds or if verify_heap is on. |
2685 heap()->fixed_array_map(); | 2688 reinterpret_cast<Object**>(object->address())[0] = |
2686 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0); | 2689 heap()->fixed_array_map(); |
2687 #endif | 2690 reinterpret_cast<Object**>(object->address())[1] = Smi::FromInt(0); |
2691 } | |
2688 | 2692 |
2689 heap()->incremental_marking()->OldSpaceStep(object_size); | 2693 heap()->incremental_marking()->OldSpaceStep(object_size); |
2690 return object; | 2694 return object; |
2691 } | 2695 } |
2692 | 2696 |
2693 | 2697 |
2694 // GC support | 2698 // GC support |
2695 MaybeObject* LargeObjectSpace::FindObject(Address a) { | 2699 MaybeObject* LargeObjectSpace::FindObject(Address a) { |
2696 LargePage* page = FindPage(a); | 2700 LargePage* page = FindPage(a); |
2697 if (page != NULL) { | 2701 if (page != NULL) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2774 bool LargeObjectSpace::Contains(HeapObject* object) { | 2778 bool LargeObjectSpace::Contains(HeapObject* object) { |
2775 Address address = object->address(); | 2779 Address address = object->address(); |
2776 MemoryChunk* chunk = MemoryChunk::FromAddress(address); | 2780 MemoryChunk* chunk = MemoryChunk::FromAddress(address); |
2777 | 2781 |
2778 bool owned = (chunk->owner() == this); | 2782 bool owned = (chunk->owner() == this); |
2779 | 2783 |
2780 SLOW_ASSERT(!owned || !FindObject(address)->IsFailure()); | 2784 SLOW_ASSERT(!owned || !FindObject(address)->IsFailure()); |
2781 | 2785 |
2782 return owned; | 2786 return owned; |
2783 } | 2787 } |
2784 | 2788 |
Michael Starzinger
2012/10/12 10:53:16
Two empty newlines between function implementation
mvstanton1
2012/10/12 11:16:27
Done.
| |
2785 | 2789 #ifdef VERIFY_HEAP |
2786 #ifdef DEBUG | |
2787 // We do not assume that the large object iterator works, because it depends | 2790 // We do not assume that the large object iterator works, because it depends |
2788 // on the invariants we are checking during verification. | 2791 // on the invariants we are checking during verification. |
2789 void LargeObjectSpace::Verify() { | 2792 void LargeObjectSpace::Verify() { |
2790 for (LargePage* chunk = first_page_; | 2793 for (LargePage* chunk = first_page_; |
2791 chunk != NULL; | 2794 chunk != NULL; |
2792 chunk = chunk->next_page()) { | 2795 chunk = chunk->next_page()) { |
2793 // Each chunk contains an object that starts at the large object page's | 2796 // Each chunk contains an object that starts at the large object page's |
2794 // object area start. | 2797 // object area start. |
2795 HeapObject* object = chunk->GetObject(); | 2798 HeapObject* object = chunk->GetObject(); |
2796 Page* page = Page::FromAddress(object->address()); | 2799 Page* page = Page::FromAddress(object->address()); |
2797 ASSERT(object->address() == page->area_start()); | 2800 CHECK(object->address() == page->area_start()); |
2798 | 2801 |
2799 // The first word should be a map, and we expect all map pointers to be | 2802 // The first word should be a map, and we expect all map pointers to be |
2800 // in map space. | 2803 // in map space. |
2801 Map* map = object->map(); | 2804 Map* map = object->map(); |
2802 ASSERT(map->IsMap()); | 2805 CHECK(map->IsMap()); |
2803 ASSERT(heap()->map_space()->Contains(map)); | 2806 CHECK(heap()->map_space()->Contains(map)); |
2804 | 2807 |
2805 // We have only code, sequential strings, external strings | 2808 // We have only code, sequential strings, external strings |
2806 // (sequential strings that have been morphed into external | 2809 // (sequential strings that have been morphed into external |
2807 // strings), fixed arrays, and byte arrays in large object space. | 2810 // strings), fixed arrays, and byte arrays in large object space. |
2808 ASSERT(object->IsCode() || object->IsSeqString() || | 2811 CHECK(object->IsCode() || object->IsSeqString() || |
2809 object->IsExternalString() || object->IsFixedArray() || | 2812 object->IsExternalString() || object->IsFixedArray() || |
2810 object->IsFixedDoubleArray() || object->IsByteArray()); | 2813 object->IsFixedDoubleArray() || object->IsByteArray()); |
2811 | 2814 |
2812 // The object itself should look OK. | 2815 // The object itself should look OK. |
2813 object->Verify(); | 2816 object->Verify(); |
2814 | 2817 |
2815 // Byte arrays and strings don't have interior pointers. | 2818 // Byte arrays and strings don't have interior pointers. |
2816 if (object->IsCode()) { | 2819 if (object->IsCode()) { |
2817 VerifyPointersVisitor code_visitor; | 2820 VerifyPointersVisitor code_visitor; |
2818 object->IterateBody(map->instance_type(), | 2821 object->IterateBody(map->instance_type(), |
2819 object->Size(), | 2822 object->Size(), |
2820 &code_visitor); | 2823 &code_visitor); |
2821 } else if (object->IsFixedArray()) { | 2824 } else if (object->IsFixedArray()) { |
2822 FixedArray* array = FixedArray::cast(object); | 2825 FixedArray* array = FixedArray::cast(object); |
2823 for (int j = 0; j < array->length(); j++) { | 2826 for (int j = 0; j < array->length(); j++) { |
2824 Object* element = array->get(j); | 2827 Object* element = array->get(j); |
2825 if (element->IsHeapObject()) { | 2828 if (element->IsHeapObject()) { |
2826 HeapObject* element_object = HeapObject::cast(element); | 2829 HeapObject* element_object = HeapObject::cast(element); |
2827 ASSERT(heap()->Contains(element_object)); | 2830 CHECK(heap()->Contains(element_object)); |
2828 ASSERT(element_object->map()->IsMap()); | 2831 CHECK(element_object->map()->IsMap()); |
2829 } | 2832 } |
2830 } | 2833 } |
2831 } | 2834 } |
2832 } | 2835 } |
2833 } | 2836 } |
2837 #endif | |
2834 | 2838 |
Michael Starzinger
2012/10/12 10:53:16
Two empty newlines between function implementation
mvstanton1
2012/10/12 11:16:27
Done.
| |
2835 | 2839 #ifdef DEBUG |
2836 void LargeObjectSpace::Print() { | 2840 void LargeObjectSpace::Print() { |
2837 LargeObjectIterator it(this); | 2841 LargeObjectIterator it(this); |
2838 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 2842 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
2839 obj->Print(); | 2843 obj->Print(); |
2840 } | 2844 } |
2841 } | 2845 } |
2842 | 2846 |
2843 | 2847 |
2844 void LargeObjectSpace::ReportStatistics() { | 2848 void LargeObjectSpace::ReportStatistics() { |
2845 PrintF(" size: %" V8_PTR_PREFIX "d\n", size_); | 2849 PrintF(" size: %" V8_PTR_PREFIX "d\n", size_); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2888 object->ShortPrint(); | 2892 object->ShortPrint(); |
2889 PrintF("\n"); | 2893 PrintF("\n"); |
2890 } | 2894 } |
2891 printf(" --------------------------------------\n"); | 2895 printf(" --------------------------------------\n"); |
2892 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 2896 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
2893 } | 2897 } |
2894 | 2898 |
2895 #endif // DEBUG | 2899 #endif // DEBUG |
2896 | 2900 |
2897 } } // namespace v8::internal | 2901 } } // namespace v8::internal |
OLD | NEW |