| OLD | NEW |
| 1 // Copyright 2006-2010 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2010 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 code_range_ = new VirtualMemory(requested); | 163 code_range_ = new VirtualMemory(requested); |
| 164 CHECK(code_range_ != NULL); | 164 CHECK(code_range_ != NULL); |
| 165 if (!code_range_->IsReserved()) { | 165 if (!code_range_->IsReserved()) { |
| 166 delete code_range_; | 166 delete code_range_; |
| 167 code_range_ = NULL; | 167 code_range_ = NULL; |
| 168 return false; | 168 return false; |
| 169 } | 169 } |
| 170 | 170 |
| 171 // We are sure that we have mapped a block of requested addresses. | 171 // We are sure that we have mapped a block of requested addresses. |
| 172 ASSERT(code_range_->size() == requested); | 172 ASSERT(code_range_->size() == requested); |
| 173 LOG(NewEvent("CodeRange", code_range_->address(), requested)); | 173 LOG(isolate_, NewEvent("CodeRange", code_range_->address(), requested)); |
| 174 allocation_list_.Add(FreeBlock(code_range_->address(), code_range_->size())); | 174 allocation_list_.Add(FreeBlock(code_range_->address(), code_range_->size())); |
| 175 current_allocation_block_index_ = 0; | 175 current_allocation_block_index_ = 0; |
| 176 return true; | 176 return true; |
| 177 } | 177 } |
| 178 | 178 |
| 179 | 179 |
| 180 int CodeRange::CompareFreeBlockAddress(const FreeBlock* left, | 180 int CodeRange::CompareFreeBlockAddress(const FreeBlock* left, |
| 181 const FreeBlock* right) { | 181 const FreeBlock* right) { |
| 182 // The entire point of CodeRange is that the difference between two | 182 // The entire point of CodeRange is that the difference between two |
| 183 // addresses in the range can be represented as a signed 32-bit int, | 183 // addresses in the range can be represented as a signed 32-bit int, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 | 337 |
| 338 | 338 |
| 339 void MemoryAllocator::TearDown() { | 339 void MemoryAllocator::TearDown() { |
| 340 for (int i = 0; i < max_nof_chunks_; i++) { | 340 for (int i = 0; i < max_nof_chunks_; i++) { |
| 341 if (chunks_[i].address() != NULL) DeleteChunk(i); | 341 if (chunks_[i].address() != NULL) DeleteChunk(i); |
| 342 } | 342 } |
| 343 chunks_.Clear(); | 343 chunks_.Clear(); |
| 344 free_chunk_ids_.Clear(); | 344 free_chunk_ids_.Clear(); |
| 345 | 345 |
| 346 if (initial_chunk_ != NULL) { | 346 if (initial_chunk_ != NULL) { |
| 347 LOG(DeleteEvent("InitialChunk", initial_chunk_->address())); | 347 LOG(isolate_, DeleteEvent("InitialChunk", initial_chunk_->address())); |
| 348 delete initial_chunk_; | 348 delete initial_chunk_; |
| 349 initial_chunk_ = NULL; | 349 initial_chunk_ = NULL; |
| 350 } | 350 } |
| 351 | 351 |
| 352 ASSERT(top_ == max_nof_chunks_); // all chunks are free | 352 ASSERT(top_ == max_nof_chunks_); // all chunks are free |
| 353 top_ = 0; | 353 top_ = 0; |
| 354 capacity_ = 0; | 354 capacity_ = 0; |
| 355 capacity_executable_ = 0; | 355 capacity_executable_ = 0; |
| 356 size_ = 0; | 356 size_ = 0; |
| 357 max_nof_chunks_ = 0; | 357 max_nof_chunks_ = 0; |
| 358 } | 358 } |
| 359 | 359 |
| 360 | 360 |
| 361 void* MemoryAllocator::AllocateRawMemory(const size_t requested, | 361 void* MemoryAllocator::AllocateRawMemory(const size_t requested, |
| 362 size_t* allocated, | 362 size_t* allocated, |
| 363 Executability executable) { | 363 Executability executable) { |
| 364 if (size_ + static_cast<size_t>(requested) > static_cast<size_t>(capacity_)) { | 364 if (size_ + static_cast<size_t>(requested) > static_cast<size_t>(capacity_)) { |
| 365 return NULL; | 365 return NULL; |
| 366 } | 366 } |
| 367 | 367 |
| 368 void* mem; | 368 void* mem; |
| 369 if (executable == EXECUTABLE) { | 369 if (executable == EXECUTABLE) { |
| 370 // Check executable memory limit. | 370 // Check executable memory limit. |
| 371 if (size_executable_ + requested > | 371 if (size_executable_ + requested > |
| 372 static_cast<size_t>(capacity_executable_)) { | 372 static_cast<size_t>(capacity_executable_)) { |
| 373 LOG(StringEvent("MemoryAllocator::AllocateRawMemory", | 373 LOG(isolate_, |
| 374 StringEvent("MemoryAllocator::AllocateRawMemory", |
| 374 "V8 Executable Allocation capacity exceeded")); | 375 "V8 Executable Allocation capacity exceeded")); |
| 375 return NULL; | 376 return NULL; |
| 376 } | 377 } |
| 377 // Allocate executable memory either from code range or from the | 378 // Allocate executable memory either from code range or from the |
| 378 // OS. | 379 // OS. |
| 379 if (isolate_->code_range()->exists()) { | 380 if (isolate_->code_range()->exists()) { |
| 380 mem = isolate_->code_range()->AllocateRawMemory(requested, allocated); | 381 mem = isolate_->code_range()->AllocateRawMemory(requested, allocated); |
| 381 } else { | 382 } else { |
| 382 mem = OS::Allocate(requested, allocated, true); | 383 mem = OS::Allocate(requested, allocated, true); |
| 383 } | 384 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 initial_chunk_ = new VirtualMemory(requested); | 469 initial_chunk_ = new VirtualMemory(requested); |
| 469 CHECK(initial_chunk_ != NULL); | 470 CHECK(initial_chunk_ != NULL); |
| 470 if (!initial_chunk_->IsReserved()) { | 471 if (!initial_chunk_->IsReserved()) { |
| 471 delete initial_chunk_; | 472 delete initial_chunk_; |
| 472 initial_chunk_ = NULL; | 473 initial_chunk_ = NULL; |
| 473 return NULL; | 474 return NULL; |
| 474 } | 475 } |
| 475 | 476 |
| 476 // We are sure that we have mapped a block of requested addresses. | 477 // We are sure that we have mapped a block of requested addresses. |
| 477 ASSERT(initial_chunk_->size() == requested); | 478 ASSERT(initial_chunk_->size() == requested); |
| 478 LOG(NewEvent("InitialChunk", initial_chunk_->address(), requested)); | 479 LOG(isolate_, |
| 480 NewEvent("InitialChunk", initial_chunk_->address(), requested)); |
| 479 size_ += static_cast<int>(requested); | 481 size_ += static_cast<int>(requested); |
| 480 return initial_chunk_->address(); | 482 return initial_chunk_->address(); |
| 481 } | 483 } |
| 482 | 484 |
| 483 | 485 |
| 484 static int PagesInChunk(Address start, size_t size) { | 486 static int PagesInChunk(Address start, size_t size) { |
| 485 // The first page starts on the first page-aligned address from start onward | 487 // The first page starts on the first page-aligned address from start onward |
| 486 // and the last page ends on the last page-aligned address before | 488 // and the last page ends on the last page-aligned address before |
| 487 // start+size. Page::kPageSize is a power of two so we can divide by | 489 // start+size. Page::kPageSize is a power of two so we can divide by |
| 488 // shifting. | 490 // shifting. |
| 489 return static_cast<int>((RoundDown(start + size, Page::kPageSize) | 491 return static_cast<int>((RoundDown(start + size, Page::kPageSize) |
| 490 - RoundUp(start, Page::kPageSize)) >> kPageSizeBits); | 492 - RoundUp(start, Page::kPageSize)) >> kPageSizeBits); |
| 491 } | 493 } |
| 492 | 494 |
| 493 | 495 |
| 494 Page* MemoryAllocator::AllocatePages(int requested_pages, | 496 Page* MemoryAllocator::AllocatePages(int requested_pages, |
| 495 int* allocated_pages, | 497 int* allocated_pages, |
| 496 PagedSpace* owner) { | 498 PagedSpace* owner) { |
| 497 if (requested_pages <= 0) return Page::FromAddress(NULL); | 499 if (requested_pages <= 0) return Page::FromAddress(NULL); |
| 498 size_t chunk_size = requested_pages * Page::kPageSize; | 500 size_t chunk_size = requested_pages * Page::kPageSize; |
| 499 | 501 |
| 500 void* chunk = AllocateRawMemory(chunk_size, &chunk_size, owner->executable()); | 502 void* chunk = AllocateRawMemory(chunk_size, &chunk_size, owner->executable()); |
| 501 if (chunk == NULL) return Page::FromAddress(NULL); | 503 if (chunk == NULL) return Page::FromAddress(NULL); |
| 502 LOG(NewEvent("PagedChunk", chunk, chunk_size)); | 504 LOG(isolate_, NewEvent("PagedChunk", chunk, chunk_size)); |
| 503 | 505 |
| 504 *allocated_pages = PagesInChunk(static_cast<Address>(chunk), chunk_size); | 506 *allocated_pages = PagesInChunk(static_cast<Address>(chunk), chunk_size); |
| 505 // We may 'lose' a page due to alignment. | 507 // We may 'lose' a page due to alignment. |
| 506 ASSERT(*allocated_pages >= kPagesPerChunk - 1); | 508 ASSERT(*allocated_pages >= kPagesPerChunk - 1); |
| 507 if (*allocated_pages == 0) { | 509 if (*allocated_pages == 0) { |
| 508 FreeRawMemory(chunk, chunk_size, owner->executable()); | 510 FreeRawMemory(chunk, chunk_size, owner->executable()); |
| 509 LOG(DeleteEvent("PagedChunk", chunk)); | 511 LOG(isolate_, DeleteEvent("PagedChunk", chunk)); |
| 510 return Page::FromAddress(NULL); | 512 return Page::FromAddress(NULL); |
| 511 } | 513 } |
| 512 | 514 |
| 513 int chunk_id = Pop(); | 515 int chunk_id = Pop(); |
| 514 chunks_[chunk_id].init(static_cast<Address>(chunk), chunk_size, owner); | 516 chunks_[chunk_id].init(static_cast<Address>(chunk), chunk_size, owner); |
| 515 | 517 |
| 516 ObjectSpace space = static_cast<ObjectSpace>(1 << owner->identity()); | 518 ObjectSpace space = static_cast<ObjectSpace>(1 << owner->identity()); |
| 517 PerformAllocationCallback(space, kAllocationActionAllocate, chunk_size); | 519 PerformAllocationCallback(space, kAllocationActionAllocate, chunk_size); |
| 518 Page* new_pages = InitializePagesInChunk(chunk_id, *allocated_pages, owner); | 520 Page* new_pages = InitializePagesInChunk(chunk_id, *allocated_pages, owner); |
| 519 | 521 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 | 670 |
| 669 // We cannot free a chunk contained in the initial chunk because it was not | 671 // We cannot free a chunk contained in the initial chunk because it was not |
| 670 // allocated with AllocateRawMemory. Instead we uncommit the virtual | 672 // allocated with AllocateRawMemory. Instead we uncommit the virtual |
| 671 // memory. | 673 // memory. |
| 672 if (InInitialChunk(c.address())) { | 674 if (InInitialChunk(c.address())) { |
| 673 // TODO(1240712): VirtualMemory::Uncommit has a return value which | 675 // TODO(1240712): VirtualMemory::Uncommit has a return value which |
| 674 // is ignored here. | 676 // is ignored here. |
| 675 initial_chunk_->Uncommit(c.address(), c.size()); | 677 initial_chunk_->Uncommit(c.address(), c.size()); |
| 676 COUNTERS->memory_allocated()->Decrement(static_cast<int>(c.size())); | 678 COUNTERS->memory_allocated()->Decrement(static_cast<int>(c.size())); |
| 677 } else { | 679 } else { |
| 678 LOG(DeleteEvent("PagedChunk", c.address())); | 680 LOG(isolate_, DeleteEvent("PagedChunk", c.address())); |
| 679 ObjectSpace space = static_cast<ObjectSpace>(1 << c.owner_identity()); | 681 ObjectSpace space = static_cast<ObjectSpace>(1 << c.owner_identity()); |
| 680 size_t size = c.size(); | 682 size_t size = c.size(); |
| 681 FreeRawMemory(c.address(), size, c.executable()); | 683 FreeRawMemory(c.address(), size, c.executable()); |
| 682 PerformAllocationCallback(space, kAllocationActionFree, size); | 684 PerformAllocationCallback(space, kAllocationActionFree, size); |
| 683 } | 685 } |
| 684 c.init(NULL, 0, NULL); | 686 c.init(NULL, 0, NULL); |
| 685 Push(chunk_id); | 687 Push(chunk_id); |
| 686 } | 688 } |
| 687 | 689 |
| 688 | 690 |
| (...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1652 // flag is set. | 1654 // flag is set. |
| 1653 void NewSpace::CollectStatistics() { | 1655 void NewSpace::CollectStatistics() { |
| 1654 ClearHistograms(); | 1656 ClearHistograms(); |
| 1655 SemiSpaceIterator it(this); | 1657 SemiSpaceIterator it(this); |
| 1656 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) | 1658 for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) |
| 1657 RecordAllocation(obj); | 1659 RecordAllocation(obj); |
| 1658 } | 1660 } |
| 1659 | 1661 |
| 1660 | 1662 |
| 1661 #ifdef ENABLE_LOGGING_AND_PROFILING | 1663 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1662 static void DoReportStatistics(HistogramInfo* info, const char* description) { | 1664 static void DoReportStatistics(Isolate* isolate, |
| 1663 LOG(HeapSampleBeginEvent("NewSpace", description)); | 1665 HistogramInfo* info, const char* description) { |
| 1666 LOG(isolate, HeapSampleBeginEvent("NewSpace", description)); |
| 1664 // Lump all the string types together. | 1667 // Lump all the string types together. |
| 1665 int string_number = 0; | 1668 int string_number = 0; |
| 1666 int string_bytes = 0; | 1669 int string_bytes = 0; |
| 1667 #define INCREMENT(type, size, name, camel_name) \ | 1670 #define INCREMENT(type, size, name, camel_name) \ |
| 1668 string_number += info[type].number(); \ | 1671 string_number += info[type].number(); \ |
| 1669 string_bytes += info[type].bytes(); | 1672 string_bytes += info[type].bytes(); |
| 1670 STRING_TYPE_LIST(INCREMENT) | 1673 STRING_TYPE_LIST(INCREMENT) |
| 1671 #undef INCREMENT | 1674 #undef INCREMENT |
| 1672 if (string_number > 0) { | 1675 if (string_number > 0) { |
| 1673 LOG(HeapSampleItemEvent("STRING_TYPE", string_number, string_bytes)); | 1676 LOG(isolate, |
| 1677 HeapSampleItemEvent("STRING_TYPE", string_number, string_bytes)); |
| 1674 } | 1678 } |
| 1675 | 1679 |
| 1676 // Then do the other types. | 1680 // Then do the other types. |
| 1677 for (int i = FIRST_NONSTRING_TYPE; i <= LAST_TYPE; ++i) { | 1681 for (int i = FIRST_NONSTRING_TYPE; i <= LAST_TYPE; ++i) { |
| 1678 if (info[i].number() > 0) { | 1682 if (info[i].number() > 0) { |
| 1679 LOG(HeapSampleItemEvent(info[i].name(), info[i].number(), | 1683 LOG(isolate, |
| 1684 HeapSampleItemEvent(info[i].name(), info[i].number(), |
| 1680 info[i].bytes())); | 1685 info[i].bytes())); |
| 1681 } | 1686 } |
| 1682 } | 1687 } |
| 1683 LOG(HeapSampleEndEvent("NewSpace", description)); | 1688 LOG(isolate, HeapSampleEndEvent("NewSpace", description)); |
| 1684 } | 1689 } |
| 1685 #endif // ENABLE_LOGGING_AND_PROFILING | 1690 #endif // ENABLE_LOGGING_AND_PROFILING |
| 1686 | 1691 |
| 1687 | 1692 |
| 1688 void NewSpace::ReportStatistics() { | 1693 void NewSpace::ReportStatistics() { |
| 1689 #ifdef DEBUG | 1694 #ifdef DEBUG |
| 1690 if (FLAG_heap_stats) { | 1695 if (FLAG_heap_stats) { |
| 1691 float pct = static_cast<float>(Available()) / Capacity(); | 1696 float pct = static_cast<float>(Available()) / Capacity(); |
| 1692 PrintF(" capacity: %" V8_PTR_PREFIX "d" | 1697 PrintF(" capacity: %" V8_PTR_PREFIX "d" |
| 1693 ", available: %" V8_PTR_PREFIX "d, %%%d\n", | 1698 ", available: %" V8_PTR_PREFIX "d, %%%d\n", |
| 1694 Capacity(), Available(), static_cast<int>(pct*100)); | 1699 Capacity(), Available(), static_cast<int>(pct*100)); |
| 1695 PrintF("\n Object Histogram:\n"); | 1700 PrintF("\n Object Histogram:\n"); |
| 1696 for (int i = 0; i <= LAST_TYPE; i++) { | 1701 for (int i = 0; i <= LAST_TYPE; i++) { |
| 1697 if (allocated_histogram_[i].number() > 0) { | 1702 if (allocated_histogram_[i].number() > 0) { |
| 1698 PrintF(" %-34s%10d (%10d bytes)\n", | 1703 PrintF(" %-34s%10d (%10d bytes)\n", |
| 1699 allocated_histogram_[i].name(), | 1704 allocated_histogram_[i].name(), |
| 1700 allocated_histogram_[i].number(), | 1705 allocated_histogram_[i].number(), |
| 1701 allocated_histogram_[i].bytes()); | 1706 allocated_histogram_[i].bytes()); |
| 1702 } | 1707 } |
| 1703 } | 1708 } |
| 1704 PrintF("\n"); | 1709 PrintF("\n"); |
| 1705 } | 1710 } |
| 1706 #endif // DEBUG | 1711 #endif // DEBUG |
| 1707 | 1712 |
| 1708 #ifdef ENABLE_LOGGING_AND_PROFILING | 1713 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1709 if (FLAG_log_gc) { | 1714 if (FLAG_log_gc) { |
| 1710 DoReportStatistics(allocated_histogram_, "allocated"); | 1715 Isolate* isolate = ISOLATE; |
| 1711 DoReportStatistics(promoted_histogram_, "promoted"); | 1716 DoReportStatistics(isolate, allocated_histogram_, "allocated"); |
| 1717 DoReportStatistics(isolate, promoted_histogram_, "promoted"); |
| 1712 } | 1718 } |
| 1713 #endif // ENABLE_LOGGING_AND_PROFILING | 1719 #endif // ENABLE_LOGGING_AND_PROFILING |
| 1714 } | 1720 } |
| 1715 | 1721 |
| 1716 | 1722 |
| 1717 void NewSpace::RecordAllocation(HeapObject* obj) { | 1723 void NewSpace::RecordAllocation(HeapObject* obj) { |
| 1718 InstanceType type = obj->map()->instance_type(); | 1724 InstanceType type = obj->map()->instance_type(); |
| 1719 ASSERT(0 <= type && type <= LAST_TYPE); | 1725 ASSERT(0 <= type && type <= LAST_TYPE); |
| 1720 allocated_histogram_[type].increment_number(1); | 1726 allocated_histogram_[type].increment_number(1); |
| 1721 allocated_histogram_[type].increment_bytes(obj->Size()); | 1727 allocated_histogram_[type].increment_bytes(obj->Size()); |
| (...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2709 } | 2715 } |
| 2710 | 2716 |
| 2711 | 2717 |
| 2712 // ----------------------------------------------------------------------------- | 2718 // ----------------------------------------------------------------------------- |
| 2713 // LargeObjectChunk | 2719 // LargeObjectChunk |
| 2714 | 2720 |
| 2715 LargeObjectChunk* LargeObjectChunk::New(int size_in_bytes, | 2721 LargeObjectChunk* LargeObjectChunk::New(int size_in_bytes, |
| 2716 Executability executable) { | 2722 Executability executable) { |
| 2717 size_t requested = ChunkSizeFor(size_in_bytes); | 2723 size_t requested = ChunkSizeFor(size_in_bytes); |
| 2718 size_t size; | 2724 size_t size; |
| 2719 void* mem = Isolate::Current()->memory_allocator()->AllocateRawMemory( | 2725 Isolate* isolate = Isolate::Current(); |
| 2726 void* mem = isolate->memory_allocator()->AllocateRawMemory( |
| 2720 requested, &size, executable); | 2727 requested, &size, executable); |
| 2721 if (mem == NULL) return NULL; | 2728 if (mem == NULL) return NULL; |
| 2722 | 2729 |
| 2723 // The start of the chunk may be overlayed with a page so we have to | 2730 // The start of the chunk may be overlayed with a page so we have to |
| 2724 // make sure that the page flags fit in the size field. | 2731 // make sure that the page flags fit in the size field. |
| 2725 ASSERT((size & Page::kPageFlagMask) == 0); | 2732 ASSERT((size & Page::kPageFlagMask) == 0); |
| 2726 | 2733 |
| 2727 LOG(NewEvent("LargeObjectChunk", mem, size)); | 2734 LOG(isolate, NewEvent("LargeObjectChunk", mem, size)); |
| 2728 if (size < requested) { | 2735 if (size < requested) { |
| 2729 Isolate::Current()->memory_allocator()->FreeRawMemory( | 2736 isolate->memory_allocator()->FreeRawMemory( |
| 2730 mem, size, executable); | 2737 mem, size, executable); |
| 2731 LOG(DeleteEvent("LargeObjectChunk", mem)); | 2738 LOG(isolate, DeleteEvent("LargeObjectChunk", mem)); |
| 2732 return NULL; | 2739 return NULL; |
| 2733 } | 2740 } |
| 2734 | 2741 |
| 2735 ObjectSpace space = (executable == EXECUTABLE) | 2742 ObjectSpace space = (executable == EXECUTABLE) |
| 2736 ? kObjectSpaceCodeSpace | 2743 ? kObjectSpaceCodeSpace |
| 2737 : kObjectSpaceLoSpace; | 2744 : kObjectSpaceLoSpace; |
| 2738 Isolate::Current()->memory_allocator()->PerformAllocationCallback( | 2745 isolate->memory_allocator()->PerformAllocationCallback( |
| 2739 space, kAllocationActionAllocate, size); | 2746 space, kAllocationActionAllocate, size); |
| 2740 | 2747 |
| 2741 LargeObjectChunk* chunk = reinterpret_cast<LargeObjectChunk*>(mem); | 2748 LargeObjectChunk* chunk = reinterpret_cast<LargeObjectChunk*>(mem); |
| 2742 chunk->size_ = size; | 2749 chunk->size_ = size; |
| 2743 Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize)); | 2750 Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize)); |
| 2744 page->heap_ = Isolate::Current()->heap(); | 2751 page->heap_ = Isolate::Current()->heap(); |
| 2745 return chunk; | 2752 return chunk; |
| 2746 } | 2753 } |
| 2747 | 2754 |
| 2748 | 2755 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2771 page_count_ = 0; | 2778 page_count_ = 0; |
| 2772 objects_size_ = 0; | 2779 objects_size_ = 0; |
| 2773 return true; | 2780 return true; |
| 2774 } | 2781 } |
| 2775 | 2782 |
| 2776 | 2783 |
| 2777 void LargeObjectSpace::TearDown() { | 2784 void LargeObjectSpace::TearDown() { |
| 2778 while (first_chunk_ != NULL) { | 2785 while (first_chunk_ != NULL) { |
| 2779 LargeObjectChunk* chunk = first_chunk_; | 2786 LargeObjectChunk* chunk = first_chunk_; |
| 2780 first_chunk_ = first_chunk_->next(); | 2787 first_chunk_ = first_chunk_->next(); |
| 2781 LOG(DeleteEvent("LargeObjectChunk", chunk->address())); | 2788 LOG(heap()->isolate(), DeleteEvent("LargeObjectChunk", chunk->address())); |
| 2782 Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize)); | 2789 Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize)); |
| 2783 Executability executable = | 2790 Executability executable = |
| 2784 page->IsPageExecutable() ? EXECUTABLE : NOT_EXECUTABLE; | 2791 page->IsPageExecutable() ? EXECUTABLE : NOT_EXECUTABLE; |
| 2785 ObjectSpace space = kObjectSpaceLoSpace; | 2792 ObjectSpace space = kObjectSpaceLoSpace; |
| 2786 if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace; | 2793 if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace; |
| 2787 size_t size = chunk->size(); | 2794 size_t size = chunk->size(); |
| 2788 heap()->isolate()->memory_allocator()->FreeRawMemory(chunk->address(), | 2795 heap()->isolate()->memory_allocator()->FreeRawMemory(chunk->address(), |
| 2789 size, | 2796 size, |
| 2790 executable); | 2797 executable); |
| 2791 heap()->isolate()->memory_allocator()->PerformAllocationCallback( | 2798 heap()->isolate()->memory_allocator()->PerformAllocationCallback( |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3007 size_ -= static_cast<int>(chunk_size); | 3014 size_ -= static_cast<int>(chunk_size); |
| 3008 objects_size_ -= object->Size(); | 3015 objects_size_ -= object->Size(); |
| 3009 page_count_--; | 3016 page_count_--; |
| 3010 ObjectSpace space = kObjectSpaceLoSpace; | 3017 ObjectSpace space = kObjectSpaceLoSpace; |
| 3011 if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace; | 3018 if (executable == EXECUTABLE) space = kObjectSpaceCodeSpace; |
| 3012 heap()->isolate()->memory_allocator()->FreeRawMemory(chunk_address, | 3019 heap()->isolate()->memory_allocator()->FreeRawMemory(chunk_address, |
| 3013 chunk_size, | 3020 chunk_size, |
| 3014 executable); | 3021 executable); |
| 3015 heap()->isolate()->memory_allocator()->PerformAllocationCallback( | 3022 heap()->isolate()->memory_allocator()->PerformAllocationCallback( |
| 3016 space, kAllocationActionFree, size_); | 3023 space, kAllocationActionFree, size_); |
| 3017 LOG(DeleteEvent("LargeObjectChunk", chunk_address)); | 3024 LOG(heap()->isolate(), DeleteEvent("LargeObjectChunk", chunk_address)); |
| 3018 } | 3025 } |
| 3019 } | 3026 } |
| 3020 } | 3027 } |
| 3021 | 3028 |
| 3022 | 3029 |
| 3023 bool LargeObjectSpace::Contains(HeapObject* object) { | 3030 bool LargeObjectSpace::Contains(HeapObject* object) { |
| 3024 Address address = object->address(); | 3031 Address address = object->address(); |
| 3025 if (heap()->new_space()->Contains(address)) { | 3032 if (heap()->new_space()->Contains(address)) { |
| 3026 return false; | 3033 return false; |
| 3027 } | 3034 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3124 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { | 3131 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { |
| 3125 if (obj->IsCode()) { | 3132 if (obj->IsCode()) { |
| 3126 Code* code = Code::cast(obj); | 3133 Code* code = Code::cast(obj); |
| 3127 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 3134 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
| 3128 } | 3135 } |
| 3129 } | 3136 } |
| 3130 } | 3137 } |
| 3131 #endif // DEBUG | 3138 #endif // DEBUG |
| 3132 | 3139 |
| 3133 } } // namespace v8::internal | 3140 } } // namespace v8::internal |
| OLD | NEW |