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