dlmalloc_space.h revision d7576328811e5103e99d31f834a857522cc1463f
11d54e73444e017d3a65234e0f193846f3e27472bIan Rogers/* 21d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * Copyright (C) 2011 The Android Open Source Project 31d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * 41d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 51d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * you may not use this file except in compliance with the License. 61d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * You may obtain a copy of the License at 71d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * 81d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 91d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * 101d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * Unless required by applicable law or agreed to in writing, software 111d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * See the License for the specific language governing permissions and 141d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * limitations under the License. 151d54e73444e017d3a65234e0f193846f3e27472bIan Rogers */ 161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_ 191d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 20cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "malloc_space.h" 211d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "space.h" 221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 231d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace art { 241d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace gc { 251d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 261d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace collector { 271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers class MarkSweep; 281d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace collector 291d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 301d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace space { 311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 326fac447555dc94a935b78198479cce645c837b89Ian Rogers// An alloc space is a space where objects may be allocated and garbage collected. Not final as may 336fac447555dc94a935b78198479cce645c837b89Ian Rogers// be overridden by a ValgrindMallocSpace. 34cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass DlMallocSpace : public MallocSpace { 351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public: 36e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier // Create a DlMallocSpace from an existing mem_map. 37e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier static DlMallocSpace* CreateFromMemMap(MemMap* mem_map, const std::string& name, 38e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier size_t starting_size, size_t initial_size, 3931f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier size_t growth_limit, size_t capacity, 4031f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier bool can_move_objects); 41e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier 42cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Create a DlMallocSpace with the requested sizes. The requested 431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // base address is not guaranteed to be granted, if it is required, 44cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // the caller should call Begin on the returned space to confirm the 45cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // request was granted. 461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers static DlMallocSpace* Create(const std::string& name, size_t initial_size, size_t growth_limit, 4713735955f39b3b304c37d2b2840663c131262c18Ian Rogers size_t capacity, uint8_t* requested_begin, bool can_move_objects); 481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 496fac447555dc94a935b78198479cce645c837b89Ian Rogers // Virtual to allow ValgrindMallocSpace to intercept. 506fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, size_t* bytes_allocated, 516fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t* usable_size) OVERRIDE LOCKS_EXCLUDED(lock_); 526fac447555dc94a935b78198479cce645c837b89Ian Rogers // Virtual to allow ValgrindMallocSpace to intercept. 536fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated, 546fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t* usable_size) OVERRIDE LOCKS_EXCLUDED(lock_) { 556fac447555dc94a935b78198479cce645c837b89Ian Rogers return AllocNonvirtual(self, num_bytes, bytes_allocated, usable_size); 566fac447555dc94a935b78198479cce645c837b89Ian Rogers } 576fac447555dc94a935b78198479cce645c837b89Ian Rogers // Virtual to allow ValgrindMallocSpace to intercept. 586fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual size_t AllocationSize(mirror::Object* obj, size_t* usable_size) OVERRIDE { 596fac447555dc94a935b78198479cce645c837b89Ian Rogers return AllocationSizeNonvirtual(obj, usable_size); 606fac447555dc94a935b78198479cce645c837b89Ian Rogers } 616fac447555dc94a935b78198479cce645c837b89Ian Rogers // Virtual to allow ValgrindMallocSpace to intercept. 626fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual size_t Free(Thread* self, mirror::Object* ptr) OVERRIDE 636fac447555dc94a935b78198479cce645c837b89Ian Rogers LOCKS_EXCLUDED(lock_) 64ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 656fac447555dc94a935b78198479cce645c837b89Ian Rogers // Virtual to allow ValgrindMallocSpace to intercept. 666fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) OVERRIDE 676fac447555dc94a935b78198479cce645c837b89Ian Rogers LOCKS_EXCLUDED(lock_) 68ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 706fac447555dc94a935b78198479cce645c837b89Ian Rogers // DlMallocSpaces don't have thread local state. 716fac447555dc94a935b78198479cce645c837b89Ian Rogers void RevokeThreadLocalBuffers(art::Thread*) OVERRIDE { 726fac447555dc94a935b78198479cce645c837b89Ian Rogers } 736fac447555dc94a935b78198479cce645c837b89Ian Rogers void RevokeAllThreadLocalBuffers() OVERRIDE { 7450b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi } 7550b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi 766fac447555dc94a935b78198479cce645c837b89Ian Rogers // Faster non-virtual allocation path. 776fac447555dc94a935b78198479cce645c837b89Ian Rogers mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated, 786fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t* usable_size) LOCKS_EXCLUDED(lock_); 796fac447555dc94a935b78198479cce645c837b89Ian Rogers 806fac447555dc94a935b78198479cce645c837b89Ian Rogers // Faster non-virtual allocation size path. 816fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size); 826fac447555dc94a935b78198479cce645c837b89Ian Rogers 83cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#ifndef NDEBUG 84cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Override only in the debug build. 85cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void CheckMoreCoreForPrecondition(); 86cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#endif 871d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 881d54e73444e017d3a65234e0f193846f3e27472bIan Rogers void* GetMspace() const { 891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return mspace_; 901d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 911d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 926fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t Trim() OVERRIDE; 931d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 941d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be 951d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // in use, indicated by num_bytes equaling zero. 966fac447555dc94a935b78198479cce645c837b89Ian Rogers void Walk(WalkCallback callback, void* arg) OVERRIDE LOCKS_EXCLUDED(lock_); 971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 9809b07a96094086e205948717666025909a75163bHiroshi Yamauchi // Returns the number of bytes that the space has currently obtained from the system. This is 9909b07a96094086e205948717666025909a75163bHiroshi Yamauchi // greater or equal to the amount of live data in the space. 1006fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t GetFootprint() OVERRIDE; 10109b07a96094086e205948717666025909a75163bHiroshi Yamauchi 1021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore. 1036fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t GetFootprintLimit() OVERRIDE; 1041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Set the maximum number of bytes that the heap is allowed to obtain from the system via 1061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When 1071d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow. 1086fac447555dc94a935b78198479cce645c837b89Ian Rogers void SetFootprintLimit(size_t limit) OVERRIDE; 1091d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 110d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe MallocSpace* CreateInstance(MemMap* mem_map, const std::string& name, void* allocator, 11113735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* begin, uint8_t* end, uint8_t* limit, size_t growth_limit, 11231f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier bool can_move_objects); 1131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1146fac447555dc94a935b78198479cce645c837b89Ian Rogers uint64_t GetBytesAllocated() OVERRIDE; 1156fac447555dc94a935b78198479cce645c837b89Ian Rogers uint64_t GetObjectsAllocated() OVERRIDE; 1161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 11731f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier virtual void Clear() OVERRIDE; 1180f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartier 1196fac447555dc94a935b78198479cce645c837b89Ian Rogers bool IsDlMallocSpace() const OVERRIDE { 120cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return true; 121cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 1226fac447555dc94a935b78198479cce645c837b89Ian Rogers 1236fac447555dc94a935b78198479cce645c837b89Ian Rogers DlMallocSpace* AsDlMallocSpace() OVERRIDE { 124cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return this; 125cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 126cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 127654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi void LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) OVERRIDE 128654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 129654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi 1301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected: 131d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe DlMallocSpace(MemMap* mem_map, size_t initial_size, const std::string& name, void* mspace, 132d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe uint8_t* begin, uint8_t* end, uint8_t* limit, size_t growth_limit, 133d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool can_move_objects, size_t starting_size); 1341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private: 1366fac447555dc94a935b78198479cce645c837b89Ian Rogers mirror::Object* AllocWithoutGrowthLocked(Thread* self, size_t num_bytes, size_t* bytes_allocated, 1376fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t* usable_size) 138cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(lock_); 1391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1406fac447555dc94a935b78198479cce645c837b89Ian Rogers void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size, 14126d69ffc0ebc98fbc5f316d8cd3ee6ba5b2001acHiroshi Yamauchi size_t /*maximum_size*/, bool /*low_memory_mode*/) OVERRIDE { 142cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return CreateMspace(base, morecore_start, initial_size); 143cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 144cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi static void* CreateMspace(void* base, size_t morecore_start, size_t initial_size); 1450f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartier 1461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // The boundary tag overhead. 14713735955f39b3b304c37d2b2840663c131262c18Ian Rogers static const size_t kChunkOverhead = sizeof(intptr_t); 1481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1496fac447555dc94a935b78198479cce645c837b89Ian Rogers // Underlying malloc space. 15031f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier void* mspace_; 1511d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1521d54e73444e017d3a65234e0f193846f3e27472bIan Rogers friend class collector::MarkSweep; 1531d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1541d54e73444e017d3a65234e0f193846f3e27472bIan Rogers DISALLOW_COPY_AND_ASSIGN(DlMallocSpace); 1551d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}; 1561d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1571d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace space 1581d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace gc 1591d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace art 1601d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 161fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_ 162