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 331e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov// be overridden by a MemoryToolMallocSpace. 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 491e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov // Virtual to allow MemoryToolMallocSpace to intercept. 506fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, size_t* bytes_allocated, 514460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, 524460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated) 5390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE REQUIRES(!lock_); 541e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov // Virtual to allow MemoryToolMallocSpace to intercept. 556fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated, 564460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, size_t* bytes_tl_bulk_allocated) 5790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE REQUIRES(!lock_) { 584460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi return AllocNonvirtual(self, num_bytes, bytes_allocated, usable_size, 594460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi bytes_tl_bulk_allocated); 606fac447555dc94a935b78198479cce645c837b89Ian Rogers } 611e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov // Virtual to allow MemoryToolMallocSpace to intercept. 626fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual size_t AllocationSize(mirror::Object* obj, size_t* usable_size) OVERRIDE { 636fac447555dc94a935b78198479cce645c837b89Ian Rogers return AllocationSizeNonvirtual(obj, usable_size); 646fac447555dc94a935b78198479cce645c837b89Ian Rogers } 651e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov // Virtual to allow MemoryToolMallocSpace to intercept. 666fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual size_t Free(Thread* self, mirror::Object* ptr) OVERRIDE 6790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!lock_) 68bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_); 691e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov // Virtual to allow MemoryToolMallocSpace to intercept. 706fac447555dc94a935b78198479cce645c837b89Ian Rogers virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) OVERRIDE 7190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!lock_) 72bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_); 731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 744460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t MaxBytesBulkAllocatedFor(size_t num_bytes) OVERRIDE { 754460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi return num_bytes; 764460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi } 774460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi 786fac447555dc94a935b78198479cce645c837b89Ian Rogers // DlMallocSpaces don't have thread local state. 794460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t RevokeThreadLocalBuffers(art::Thread*) OVERRIDE { 804460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi return 0U; 816fac447555dc94a935b78198479cce645c837b89Ian Rogers } 824460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t RevokeAllThreadLocalBuffers() OVERRIDE { 834460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi return 0U; 8450b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi } 8550b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi 866fac447555dc94a935b78198479cce645c837b89Ian Rogers // Faster non-virtual allocation path. 876fac447555dc94a935b78198479cce645c837b89Ian Rogers mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated, 884460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, size_t* bytes_tl_bulk_allocated) 8990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!lock_); 906fac447555dc94a935b78198479cce645c837b89Ian Rogers 916fac447555dc94a935b78198479cce645c837b89Ian Rogers // Faster non-virtual allocation size path. 926fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size); 936fac447555dc94a935b78198479cce645c837b89Ian Rogers 94cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#ifndef NDEBUG 95cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi // Override only in the debug build. 96cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi void CheckMoreCoreForPrecondition(); 97cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#endif 981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers void* GetMspace() const { 1001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return mspace_; 1011d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 1021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1036fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t Trim() OVERRIDE; 1041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be 1061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // in use, indicated by num_bytes equaling zero. 10790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void Walk(WalkCallback callback, void* arg) OVERRIDE REQUIRES(!lock_); 1081d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 10909b07a96094086e205948717666025909a75163bHiroshi Yamauchi // Returns the number of bytes that the space has currently obtained from the system. This is 11009b07a96094086e205948717666025909a75163bHiroshi Yamauchi // greater or equal to the amount of live data in the space. 1116fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t GetFootprint() OVERRIDE; 11209b07a96094086e205948717666025909a75163bHiroshi Yamauchi 1131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore. 1146fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t GetFootprintLimit() OVERRIDE; 1151d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Set the maximum number of bytes that the heap is allowed to obtain from the system via 1171d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When 1181d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow. 1196fac447555dc94a935b78198479cce645c837b89Ian Rogers void SetFootprintLimit(size_t limit) OVERRIDE; 1201d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 121d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe MallocSpace* CreateInstance(MemMap* mem_map, const std::string& name, void* allocator, 12213735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* begin, uint8_t* end, uint8_t* limit, size_t growth_limit, 12331f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier bool can_move_objects); 1241d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1256fac447555dc94a935b78198479cce645c837b89Ian Rogers uint64_t GetBytesAllocated() OVERRIDE; 1266fac447555dc94a935b78198479cce645c837b89Ian Rogers uint64_t GetObjectsAllocated() OVERRIDE; 1271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 12831f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier virtual void Clear() OVERRIDE; 1290f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartier 1306fac447555dc94a935b78198479cce645c837b89Ian Rogers bool IsDlMallocSpace() const OVERRIDE { 131cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return true; 132cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 1336fac447555dc94a935b78198479cce645c837b89Ian Rogers 1346fac447555dc94a935b78198479cce645c837b89Ian Rogers DlMallocSpace* AsDlMallocSpace() OVERRIDE { 135cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return this; 136cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 137cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi 138654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi void LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) OVERRIDE 139bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_); 140654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi 1411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected: 142d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe DlMallocSpace(MemMap* mem_map, size_t initial_size, const std::string& name, void* mspace, 143d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe uint8_t* begin, uint8_t* end, uint8_t* limit, size_t growth_limit, 144d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe bool can_move_objects, size_t starting_size); 1451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private: 1476fac447555dc94a935b78198479cce645c837b89Ian Rogers mirror::Object* AllocWithoutGrowthLocked(Thread* self, size_t num_bytes, size_t* bytes_allocated, 1484460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, 1494460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated) 15090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(lock_); 1511d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1526fac447555dc94a935b78198479cce645c837b89Ian Rogers void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size, 15326d69ffc0ebc98fbc5f316d8cd3ee6ba5b2001acHiroshi Yamauchi size_t /*maximum_size*/, bool /*low_memory_mode*/) OVERRIDE { 154cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi return CreateMspace(base, morecore_start, initial_size); 155cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi } 156cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi static void* CreateMspace(void* base, size_t morecore_start, size_t initial_size); 1570f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartier 1581d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // The boundary tag overhead. 15913735955f39b3b304c37d2b2840663c131262c18Ian Rogers static const size_t kChunkOverhead = sizeof(intptr_t); 1601d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1616fac447555dc94a935b78198479cce645c837b89Ian Rogers // Underlying malloc space. 16231f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier void* mspace_; 1631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers friend class collector::MarkSweep; 1651d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1661d54e73444e017d3a65234e0f193846f3e27472bIan Rogers DISALLOW_COPY_AND_ASSIGN(DlMallocSpace); 1671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}; 1681d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace space 1701d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace gc 1711d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace art 1721d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 173fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_ 174