malloc_space.h revision 7cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5
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#ifndef ART_RUNTIME_GC_SPACE_MALLOC_SPACE_H_ 18cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#define ART_RUNTIME_GC_SPACE_MALLOC_SPACE_H_ 19cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 20cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "space.h" 21cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 227cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi#include <valgrind.h> 237cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi#include <memcheck/memcheck.h> 247cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 25cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace art { 26cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace gc { 27cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 28cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace collector { 29cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi class MarkSweep; 30cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace collector 31cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 32cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace space { 33cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 34cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi// TODO: Remove define macro 35cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#define CHECK_MEMORY_CALL(call, args, what) \ 36cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi do { \ 37cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi int rc = call args; \ 38cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (UNLIKELY(rc != 0)) { \ 39cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi errno = rc; \ 40cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi PLOG(FATAL) << # call << " failed for " << what; \ 41cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } \ 42cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } while (false) 43cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 44cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi// const bool kUseRosAlloc = true; 45cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 46cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi// A common parent of DlMallocSpace and RosAllocSpace. 47cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass MallocSpace : public ContinuousMemMapAllocSpace { 48cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi public: 49cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi typedef void(*WalkCallback)(void *start, void *end, size_t num_bytes, void* callback_arg); 50cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 51cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi SpaceType GetType() const { 52cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi if (GetGcRetentionPolicy() == kGcRetentionPolicyFullCollect) { 53cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return kSpaceTypeZygoteSpace; 54cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } else { 55cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return kSpaceTypeAllocSpace; 56cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 57cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 58cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 59cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Allocate num_bytes without allowing the underlying space to grow. 60cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, 61cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t* bytes_allocated) = 0; 62cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Allocate num_bytes allowing the underlying space to grow. 63cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated) = 0; 64cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Return the storage space required by obj. 65cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual size_t AllocationSize(const mirror::Object* obj) = 0; 66cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual size_t Free(Thread* self, mirror::Object* ptr) = 0; 67cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) = 0; 68cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 69cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#ifndef NDEBUG 70cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual void CheckMoreCoreForPrecondition() {} // to be overridden in the debug build. 71cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#else 72cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void CheckMoreCoreForPrecondition() {} // no-op in the non-debug build. 73cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#endif 74cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 75cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void* MoreCore(intptr_t increment); 76cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 77cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Hands unused pages back to the system. 78cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual size_t Trim() = 0; 79cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 80cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be 81cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // in use, indicated by num_bytes equaling zero. 82cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual void Walk(WalkCallback callback, void* arg) = 0; 83cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 84cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Returns the number of bytes that the space has currently obtained from the system. This is 85cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // greater or equal to the amount of live data in the space. 86cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual size_t GetFootprint() = 0; 87cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 88cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore. 89cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual size_t GetFootprintLimit() = 0; 90cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 91cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Set the maximum number of bytes that the heap is allowed to obtain from the system via 92cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When 93cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow. 94cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual void SetFootprintLimit(size_t limit) = 0; 95cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 96cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Removes the fork time growth limit on capacity, allowing the application to allocate up to the 97cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // maximum reserved size of the heap. 98cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void ClearGrowthLimit() { 99cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi growth_limit_ = NonGrowthLimitCapacity(); 100cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 101cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 102cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Override capacity so that we only return the possibly limited capacity 103cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t Capacity() const { 104cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return growth_limit_; 105cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 106cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 107cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // The total amount of memory reserved for the alloc space. 108cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t NonGrowthLimitCapacity() const { 109cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return GetMemMap()->Size(); 110cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 111cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 112cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi accounting::SpaceBitmap* GetLiveBitmap() const { 113cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return live_bitmap_.get(); 114cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 115cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 116cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi accounting::SpaceBitmap* GetMarkBitmap() const { 117cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return mark_bitmap_.get(); 118cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 119cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 120cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void Dump(std::ostream& os) const; 121cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 122cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void SetGrowthLimit(size_t growth_limit); 123cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 124cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Swap the live and mark bitmaps of this space. This is used by the GC for concurrent sweeping. 125cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void SwapBitmaps(); 126cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 127cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual MallocSpace* CreateInstance(const std::string& name, MemMap* mem_map, void* allocator, 128cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi byte* begin, byte* end, byte* limit, size_t growth_limit) = 0; 129cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 130cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Turn ourself into a zygote space and return a new alloc space which has our unused memory. 131cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi MallocSpace* CreateZygoteSpace(const char* alloc_space_name); 132cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 133cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual uint64_t GetBytesAllocated() = 0; 134cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual uint64_t GetObjectsAllocated() = 0; 135cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual uint64_t GetTotalBytesAllocated() = 0; 136cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual uint64_t GetTotalObjectsAllocated() = 0; 137cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 138cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Returns the old mark bitmap. 139cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi accounting::SpaceBitmap* BindLiveToMarkBitmap(); 140cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi bool HasBoundBitmaps() const; 141cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void UnBindBitmaps(); 142cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 143cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Returns the class of a recently freed object. 144cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi mirror::Class* FindRecentFreedObject(const mirror::Object* obj); 145cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 146cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Used to ensure that failure happens when you free / allocate into an invalidated space. If we 147cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // don't do this we may get heap corruption instead of a segfault at null. 148cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual void InvalidateAllocator() = 0; 149cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 150cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi protected: 151cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi MallocSpace(const std::string& name, MemMap* mem_map, byte* begin, byte* end, 152cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi byte* limit, size_t growth_limit); 153cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 154cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi static MemMap* CreateMemMap(const std::string& name, size_t starting_size, size_t* initial_size, 155cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t* growth_limit, size_t* capacity, byte* requested_begin); 156cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 157cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi virtual void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size) = 0; 158cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 159cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void RegisterRecentFree(mirror::Object* ptr) EXCLUSIVE_LOCKS_REQUIRED(lock_); 160cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 161cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi UniquePtr<accounting::SpaceBitmap> live_bitmap_; 162cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi UniquePtr<accounting::SpaceBitmap> mark_bitmap_; 163cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi UniquePtr<accounting::SpaceBitmap> temp_bitmap_; 164cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 165cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Recent allocation buffer. 166cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi static constexpr size_t kRecentFreeCount = kDebugSpaces ? (1 << 16) : 0; 167cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi static constexpr size_t kRecentFreeMask = kRecentFreeCount - 1; 168cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi std::pair<const mirror::Object*, mirror::Class*> recent_freed_objects_[kRecentFreeCount]; 169cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t recent_free_pos_; 170cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 171cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi static size_t bitmap_index_; 172cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 173cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Used to ensure mutual exclusion when the allocation spaces data structures are being modified. 174cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 175cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 176cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // The capacity of the alloc space until such time that ClearGrowthLimit is called. 177cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // The underlying mem_map_ controls the maximum size we allow the heap to grow to. The growth 178cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // limit is a value <= to the mem_map_ capacity used for ergonomic reasons because of the zygote. 179cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Prior to forking the zygote the heap will have a maximally sized mem_map_ but the growth_limit_ 180cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // will be set to a lower value. The growth_limit_ is used as the capacity of the alloc_space_, 181cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // however, capacity normally can't vary. In the case of the growth_limit_ it can be cleared 182cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // one time by a call to ClearGrowthLimit. 183cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi size_t growth_limit_; 184cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 185cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi friend class collector::MarkSweep; 186cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 187e5eedcb4a634246d1f912992853441f715d705ccHiroshi Yamauchi private: 188cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi DISALLOW_COPY_AND_ASSIGN(MallocSpace); 189cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi}; 190cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 1917cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi// Number of bytes to use as a red zone (rdz). A red zone of this size will be placed before and 1927cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi// after each allocation. 8 bytes provides long/double alignment. 1937cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchistatic constexpr size_t kValgrindRedZoneBytes = 8; 1947cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 1957cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi// A specialization of DlMallocSpace/RosAllocSpace that provides information to valgrind wrt allocations. 1967cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchitemplate <typename BaseMallocSpaceType, typename AllocatorType> 1977cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchiclass ValgrindMallocSpace : public BaseMallocSpaceType { 1987cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi public: 1997cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, size_t* bytes_allocated) { 2007cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi void* obj_with_rdz = BaseMallocSpaceType::AllocWithGrowth(self, num_bytes + 2 * kValgrindRedZoneBytes, 2017cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi bytes_allocated); 2027cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi if (obj_with_rdz == NULL) { 2037cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi return NULL; 2047cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2057cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi mirror::Object* result = reinterpret_cast<mirror::Object*>( 2067cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi reinterpret_cast<byte*>(obj_with_rdz) + kValgrindRedZoneBytes); 2077cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi // Make redzones as no access. 2087cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi VALGRIND_MAKE_MEM_NOACCESS(obj_with_rdz, kValgrindRedZoneBytes); 2097cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi VALGRIND_MAKE_MEM_NOACCESS(reinterpret_cast<byte*>(result) + num_bytes, kValgrindRedZoneBytes); 2107cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi return result; 2117cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2127cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 2137cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated) { 2147cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi void* obj_with_rdz = BaseMallocSpaceType::Alloc(self, num_bytes + 2 * kValgrindRedZoneBytes, 2157cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi bytes_allocated); 2167cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi if (obj_with_rdz == NULL) { 2177cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi return NULL; 2187cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2197cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi mirror::Object* result = reinterpret_cast<mirror::Object*>( 2207cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi reinterpret_cast<byte*>(obj_with_rdz) + kValgrindRedZoneBytes); 2217cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi // Make redzones as no access. 2227cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi VALGRIND_MAKE_MEM_NOACCESS(obj_with_rdz, kValgrindRedZoneBytes); 2237cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi VALGRIND_MAKE_MEM_NOACCESS(reinterpret_cast<byte*>(result) + num_bytes, kValgrindRedZoneBytes); 2247cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi return result; 2257cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2267cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 2277cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi virtual size_t AllocationSize(const mirror::Object* obj) { 2287cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi size_t result = BaseMallocSpaceType::AllocationSize(reinterpret_cast<const mirror::Object*>( 2297cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi reinterpret_cast<const byte*>(obj) - kValgrindRedZoneBytes)); 2307cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi return result - 2 * kValgrindRedZoneBytes; 2317cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2327cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 2337cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi virtual size_t Free(Thread* self, mirror::Object* ptr) { 2347cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi void* obj_after_rdz = reinterpret_cast<void*>(ptr); 2357cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi void* obj_with_rdz = reinterpret_cast<byte*>(obj_after_rdz) - kValgrindRedZoneBytes; 2367cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi // Make redzones undefined. 2377cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi size_t allocation_size = BaseMallocSpaceType::AllocationSize( 2387cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi reinterpret_cast<mirror::Object*>(obj_with_rdz)); 2397cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi VALGRIND_MAKE_MEM_UNDEFINED(obj_with_rdz, allocation_size); 2407cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi size_t freed = BaseMallocSpaceType::Free(self, reinterpret_cast<mirror::Object*>(obj_with_rdz)); 2417cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi return freed - 2 * kValgrindRedZoneBytes; 2427cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2437cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 2447cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) { 2457cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi size_t freed = 0; 2467cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi for (size_t i = 0; i < num_ptrs; i++) { 2477cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi freed += Free(self, ptrs[i]); 2487cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2497cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi return freed; 2507cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2517cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 2527cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi ValgrindMallocSpace(const std::string& name, MemMap* mem_map, AllocatorType allocator, byte* begin, 2537cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi byte* end, byte* limit, size_t growth_limit, size_t initial_size) : 2547cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi BaseMallocSpaceType(name, mem_map, allocator, begin, end, limit, growth_limit) { 2557cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi VALGRIND_MAKE_MEM_UNDEFINED(mem_map->Begin() + initial_size, mem_map->Size() - initial_size); 2567cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2577cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 2587cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi virtual ~ValgrindMallocSpace() { 2597cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi } 2607cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 2617cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi private: 2627cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi DISALLOW_COPY_AND_ASSIGN(ValgrindMallocSpace); 2637cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi}; 2647cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi 265cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace space 266cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace gc 267cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi} // namespace art 268cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 269e5eedcb4a634246d1f912992853441f715d705ccHiroshi Yamauchi#endif // ART_RUNTIME_GC_SPACE_MALLOC_SPACE_H_ 270