1cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi/* 2cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * Copyright (C) 2013 The Android Open Source Project 3cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * 4cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * Licensed under the Apache License, Version 2.0 (the "License"); 5cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * you may not use this file except in compliance with the License. 6cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * You may obtain a copy of the License at 7cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * 8cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * http://www.apache.org/licenses/LICENSE-2.0 9cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * 10cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * Unless required by applicable law or agreed to in writing, software 11cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * distributed under the License is distributed on an "AS IS" BASIS, 12cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * See the License for the specific language governing permissions and 14cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * limitations under the License. 15cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi */ 16cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 17cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "malloc_space.h" 18cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 19ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier#include "gc/accounting/card_table-inl.h" 20ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier#include "gc/accounting/space_bitmap-inl.h" 21cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "gc/heap.h" 22a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier#include "gc/space/space-inl.h" 23a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier#include "gc/space/zygote_space.h" 24cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "mirror/class-inl.h" 25cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "mirror/object-inl.h" 26cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "runtime.h" 27eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier#include "handle_scope-inl.h" 28cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "thread.h" 29cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "thread_list.h" 30cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "utils.h" 31cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 32cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace art { 33cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace gc { 34cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace space { 35cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 36cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchisize_t MallocSpace::bitmap_index_ = 0; 37cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 38cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi YamauchiMallocSpace::MallocSpace(const std::string& name, MemMap* mem_map, 3913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* begin, uint8_t* end, uint8_t* limit, size_t growth_limit, 4031f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier bool create_bitmaps, bool can_move_objects, size_t starting_size, 4131f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier size_t initial_size) 42cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi : ContinuousMemMapAllocSpace(name, mem_map, begin, end, limit, kGcRetentionPolicyAlwaysCollect), 43cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi recent_free_pos_(0), lock_("allocation space lock", kAllocSpaceLock), 4431f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier growth_limit_(growth_limit), can_move_objects_(can_move_objects), 4531f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier starting_size_(starting_size), initial_size_(initial_size) { 46a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier if (create_bitmaps) { 47a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier size_t bitmap_index = bitmap_index_++; 48a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier static const uintptr_t kGcCardSize = static_cast<uintptr_t>(accounting::CardTable::kCardSize); 49a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier CHECK(IsAligned<kGcCardSize>(reinterpret_cast<uintptr_t>(mem_map->Begin()))); 50a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier CHECK(IsAligned<kGcCardSize>(reinterpret_cast<uintptr_t>(mem_map->End()))); 51a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier live_bitmap_.reset(accounting::ContinuousSpaceBitmap::Create( 52a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier StringPrintf("allocspace %s live-bitmap %d", name.c_str(), static_cast<int>(bitmap_index)), 53447a914ab28fe7b295403189d550c2759b2777e4Hiroshi Yamauchi Begin(), NonGrowthLimitCapacity())); 542796a1669ae0f3b96db8432fbd8be1b93bf335c4Mathieu Chartier CHECK(live_bitmap_.get() != nullptr) << "could not create allocspace live bitmap #" 55a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier << bitmap_index; 56a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier mark_bitmap_.reset(accounting::ContinuousSpaceBitmap::Create( 57a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier StringPrintf("allocspace %s mark-bitmap %d", name.c_str(), static_cast<int>(bitmap_index)), 58447a914ab28fe7b295403189d550c2759b2777e4Hiroshi Yamauchi Begin(), NonGrowthLimitCapacity())); 592796a1669ae0f3b96db8432fbd8be1b93bf335c4Mathieu Chartier CHECK(live_bitmap_.get() != nullptr) << "could not create allocspace mark bitmap #" 60a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier << bitmap_index; 61a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier } 62cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi for (auto& freed : recent_freed_objects_) { 63cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi freed.first = nullptr; 64cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi freed.second = nullptr; 65cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 66cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} 67cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 68cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi YamauchiMemMap* MallocSpace::CreateMemMap(const std::string& name, size_t starting_size, size_t* initial_size, 6913735955f39b3b304c37d2b2840663c131262c18Ian Rogers size_t* growth_limit, size_t* capacity, uint8_t* requested_begin) { 70cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Sanity check arguments 71cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (starting_size > *initial_size) { 72cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi *initial_size = starting_size; 73cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 74cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (*initial_size > *growth_limit) { 75cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi LOG(ERROR) << "Failed to create alloc space (" << name << ") where the initial size (" 76cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << PrettySize(*initial_size) << ") is larger than its capacity (" 77cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << PrettySize(*growth_limit) << ")"; 782cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier return nullptr; 79cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 80cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (*growth_limit > *capacity) { 81cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi LOG(ERROR) << "Failed to create alloc space (" << name << ") where the growth limit capacity (" 82cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << PrettySize(*growth_limit) << ") is larger than the capacity (" 83cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << PrettySize(*capacity) << ")"; 842cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier return nullptr; 85cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 86cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 87cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Page align growth limit and capacity which will be used to manage mmapped storage 88cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi *growth_limit = RoundUp(*growth_limit, kPageSize); 89cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi *capacity = RoundUp(*capacity, kPageSize); 90cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 91cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi std::string error_msg; 92cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi MemMap* mem_map = MemMap::MapAnonymous(name.c_str(), requested_begin, *capacity, 935c42c29b89286e5efa4a4613132b09051ce5945bVladimir Marko PROT_READ | PROT_WRITE, true, false, &error_msg); 94e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier if (mem_map == nullptr) { 95cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi LOG(ERROR) << "Failed to allocate pages for alloc space (" << name << ") of size " 96cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << PrettySize(*capacity) << ": " << error_msg; 97cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 98cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return mem_map; 99cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} 100cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 101cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchimirror::Class* MallocSpace::FindRecentFreedObject(const mirror::Object* obj) { 102cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t pos = recent_free_pos_; 103cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Start at the most recently freed object and work our way back since there may be duplicates 104cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // caused by dlmalloc reusing memory. 105cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (kRecentFreeCount > 0) { 106cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi for (size_t i = 0; i + 1 < kRecentFreeCount + 1; ++i) { 107cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi pos = pos != 0 ? pos - 1 : kRecentFreeMask; 108cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (recent_freed_objects_[pos].first == obj) { 109cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return recent_freed_objects_[pos].second; 110cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 111cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 112cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 113cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return nullptr; 114cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} 115cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 116cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchivoid MallocSpace::RegisterRecentFree(mirror::Object* ptr) { 1174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier // No verification since the object is dead. 1184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier recent_freed_objects_[recent_free_pos_] = std::make_pair(ptr, ptr->GetClass<kVerifyNone>()); 119cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi recent_free_pos_ = (recent_free_pos_ + 1) & kRecentFreeMask; 120cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} 121cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 122cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchivoid MallocSpace::SetGrowthLimit(size_t growth_limit) { 123cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi growth_limit = RoundUp(growth_limit, kPageSize); 124cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi growth_limit_ = growth_limit; 125cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (Size() > growth_limit_) { 126be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers SetEnd(begin_ + growth_limit); 127cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 128cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} 129cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 130cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchivoid* MallocSpace::MoreCore(intptr_t increment) { 131cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi CheckMoreCoreForPrecondition(); 13213735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* original_end = End(); 133cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (increment != 0) { 134cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi VLOG(heap) << "MallocSpace::MoreCore " << PrettySize(increment); 13513735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* new_end = original_end + increment; 136cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (increment > 0) { 137cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Should never be asked to increase the allocation beyond the capacity of the space. Enforced 138cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // by mspace_set_footprint_limit. 139cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi CHECK_LE(new_end, Begin() + Capacity()); 140cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi CHECK_MEMORY_CALL(mprotect, (original_end, increment, PROT_READ | PROT_WRITE), GetName()); 141cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } else { 142cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Should never be asked for negative footprint (ie before begin). Zero footprint is ok. 143cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi CHECK_GE(original_end + increment, Begin()); 144cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Advise we don't need the pages and protect them 145cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // TODO: by removing permissions to the pages we may be causing TLB shoot-down which can be 146cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // expensive (note the same isn't true for giving permissions to a page as the protected 147cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // page shouldn't be in a TLB). We should investigate performance impact of just 148cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // removing ignoring the memory protection change here and in Space::CreateAllocSpace. It's 149cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // likely just a useful debug feature. 150cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t size = -increment; 151cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi CHECK_MEMORY_CALL(madvise, (new_end, size, MADV_DONTNEED), GetName()); 152cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi CHECK_MEMORY_CALL(mprotect, (new_end, size, PROT_NONE), GetName()); 153cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 154be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers // Update end_. 155be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers SetEnd(new_end); 156cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 157cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return original_end; 158cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} 159cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 160a1602f28c0e3127ad511712d4b08db89737ae901Mathieu ChartierZygoteSpace* MallocSpace::CreateZygoteSpace(const char* alloc_space_name, bool low_memory_mode, 161a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier MallocSpace** out_malloc_space) { 162cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // For RosAlloc, revoke thread local runs before creating a new 163cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // alloc space so that we won't mix thread local runs from different 164cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // alloc spaces. 165cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi RevokeAllThreadLocalBuffers(); 16613735955f39b3b304c37d2b2840663c131262c18Ian Rogers SetEnd(reinterpret_cast<uint8_t*>(RoundUp(reinterpret_cast<uintptr_t>(End()), kPageSize))); 167cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi DCHECK(IsAligned<accounting::CardTable::kCardSize>(begin_)); 168be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers DCHECK(IsAligned<accounting::CardTable::kCardSize>(End())); 169cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi DCHECK(IsAligned<kPageSize>(begin_)); 170be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers DCHECK(IsAligned<kPageSize>(End())); 171cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t size = RoundUp(Size(), kPageSize); 17285a43c055fcdc366293c61df6f65e586d6967841Mathieu Chartier // Trimming the heap should be done by the caller since we may have invalidated the accounting 17385a43c055fcdc366293c61df6f65e586d6967841Mathieu Chartier // stored in between objects. 174cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Remaining size is for the new alloc space. 175cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi const size_t growth_limit = growth_limit_ - size; 176d0e0d4c833b82ac2639de9dea6042ccb87fe37edLin Zang // Use mem map limit in case error for clear growth limit. 177d0e0d4c833b82ac2639de9dea6042ccb87fe37edLin Zang const size_t capacity = NonGrowthLimitCapacity() - size; 178cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi VLOG(heap) << "Begin " << reinterpret_cast<const void*>(begin_) << "\n" 179be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers << "End " << reinterpret_cast<const void*>(End()) << "\n" 180cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << "Size " << size << "\n" 181cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << "GrowthLimit " << growth_limit_ << "\n" 182cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi << "Capacity " << Capacity(); 183cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi SetGrowthLimit(RoundUp(size, kPageSize)); 184cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // FIXME: Do we need reference counted pointers here? 185cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Make the two spaces share the same mark bitmaps since the bitmaps span both of the spaces. 186cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi VLOG(heap) << "Creating new AllocSpace: "; 187cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi VLOG(heap) << "Size " << GetMemMap()->Size(); 188cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi VLOG(heap) << "GrowthLimit " << PrettySize(growth_limit); 189cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi VLOG(heap) << "Capacity " << PrettySize(capacity); 190cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Remap the tail. 191cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi std::string error_msg; 192be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers std::unique_ptr<MemMap> mem_map(GetMemMap()->RemapAtEnd(End(), alloc_space_name, 193be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers PROT_READ | PROT_WRITE, &error_msg)); 194cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi CHECK(mem_map.get() != nullptr) << error_msg; 195be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers void* allocator = CreateAllocator(End(), starting_size_, initial_size_, capacity, 196be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers low_memory_mode); 197cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Protect memory beyond the initial size. 19813735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* end = mem_map->Begin() + starting_size_; 199c4d095bba4d2cbc63ca6ca85787122c0f3e131cfMathieu Chartier if (capacity > initial_size_) { 200c4d095bba4d2cbc63ca6ca85787122c0f3e131cfMathieu Chartier CHECK_MEMORY_CALL(mprotect, (end, capacity - initial_size_, PROT_NONE), alloc_space_name); 201cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 202d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe *out_malloc_space = CreateInstance(mem_map.release(), alloc_space_name, allocator, End(), end, 20331f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier limit_, growth_limit, CanMoveObjects()); 204cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi SetLimit(End()); 205cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi live_bitmap_->SetHeapLimit(reinterpret_cast<uintptr_t>(End())); 206cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi CHECK_EQ(live_bitmap_->HeapLimit(), reinterpret_cast<uintptr_t>(End())); 207cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi mark_bitmap_->SetHeapLimit(reinterpret_cast<uintptr_t>(End())); 208cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi CHECK_EQ(mark_bitmap_->HeapLimit(), reinterpret_cast<uintptr_t>(End())); 209a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier 210a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier // Create the actual zygote space. 211a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier ZygoteSpace* zygote_space = ZygoteSpace::Create("Zygote space", ReleaseMemMap(), 212a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier live_bitmap_.release(), mark_bitmap_.release()); 213a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier if (UNLIKELY(zygote_space == nullptr)) { 214a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier VLOG(heap) << "Failed creating zygote space from space " << GetName(); 215a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier } else { 216a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier VLOG(heap) << "zygote space creation done"; 217a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier } 218a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier return zygote_space; 219cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} 220cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 221cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchivoid MallocSpace::Dump(std::ostream& os) const { 222cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi os << GetType() 223447a914ab28fe7b295403189d550c2759b2777e4Hiroshi Yamauchi << " begin=" << reinterpret_cast<void*>(Begin()) 224447a914ab28fe7b295403189d550c2759b2777e4Hiroshi Yamauchi << ",end=" << reinterpret_cast<void*>(End()) 225447a914ab28fe7b295403189d550c2759b2777e4Hiroshi Yamauchi << ",limit=" << reinterpret_cast<void*>(Limit()) 226447a914ab28fe7b295403189d550c2759b2777e4Hiroshi Yamauchi << ",size=" << PrettySize(Size()) << ",capacity=" << PrettySize(Capacity()) 227447a914ab28fe7b295403189d550c2759b2777e4Hiroshi Yamauchi << ",non_growth_limit_capacity=" << PrettySize(NonGrowthLimitCapacity()) 228447a914ab28fe7b295403189d550c2759b2777e4Hiroshi Yamauchi << ",name=\"" << GetName() << "\"]"; 229cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} 230cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 231a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartiervoid MallocSpace::SweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* arg) { 232ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier SweepCallbackContext* context = static_cast<SweepCallbackContext*>(arg); 233a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier space::MallocSpace* space = context->space->AsMallocSpace(); 234ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier Thread* self = context->self; 235ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier Locks::heap_bitmap_lock_->AssertExclusiveHeld(self); 236ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier // If the bitmaps aren't swapped we need to clear the bits since the GC isn't going to re-swap 237ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier // the bitmaps as an optimization. 238ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier if (!context->swap_bitmaps) { 239a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier accounting::ContinuousSpaceBitmap* bitmap = space->GetLiveBitmap(); 240ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier for (size_t i = 0; i < num_ptrs; ++i) { 241ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier bitmap->Clear(ptrs[i]); 242ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier } 243ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier } 244ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier // Use a bulk free, that merges consecutive objects before freeing or free per object? 245ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier // Documentation suggests better free performance with merging, but this may be at the expensive 246ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier // of allocation. 24710fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier context->freed.objects += num_ptrs; 24810fb83ad7442c8cf3356a89ec918e0786f110981Mathieu Chartier context->freed.bytes += space->FreeList(self, num_ptrs, ptrs); 249ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier} 250ec05007f8619f8b0cc868d06731e07f84bb74c5bMathieu Chartier 251379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartiervoid MallocSpace::ClampGrowthLimit() { 252379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier size_t new_capacity = Capacity(); 253379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier CHECK_LE(new_capacity, NonGrowthLimitCapacity()); 254379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier GetLiveBitmap()->SetHeapSize(new_capacity); 255379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier GetMarkBitmap()->SetHeapSize(new_capacity); 256ddac42329314587f6f188bacf101b3cb15175b3cMathieu Chartier if (temp_bitmap_.get() != nullptr) { 257ddac42329314587f6f188bacf101b3cb15175b3cMathieu Chartier // If the bitmaps are clamped, then the temp bitmap is actually the mark bitmap. 258ddac42329314587f6f188bacf101b3cb15175b3cMathieu Chartier temp_bitmap_->SetHeapSize(new_capacity); 259ddac42329314587f6f188bacf101b3cb15175b3cMathieu Chartier } 260379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier GetMemMap()->SetSize(new_capacity); 261379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier limit_ = Begin() + new_capacity; 262379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier} 263379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier 264cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace space 265cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace gc 266cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace art 267