1b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier/* 2b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * Copyright (C) 2008 The Android Open Source Project 3b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * 4b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License"); 5b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * you may not use this file except in compliance with the License. 6b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * You may obtain a copy of the License at 7b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * 8b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * http://www.apache.org/licenses/LICENSE-2.0 9b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * 10b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * Unless required by applicable law or agreed to in writing, software 11b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS, 12b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * See the License for the specific language governing permissions and 14b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier * limitations under the License. 15b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier */ 16b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_ 192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 20700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <limits.h> 21700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <stdint.h> 22700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory> 23700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <set> 24700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <vector> 25700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers 26719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "base/mutex.h" 272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "globals.h" 28b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 29b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartiernamespace art { 301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 322ffb703bf431d74326c88266b4ddaf225eb3c6adIgor Murashkinclass Class; 332ffb703bf431d74326c88266b4ddaf225eb3c6adIgor Murashkinclass Object; 342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 35576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogersclass MemMap; 36b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 371d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace gc { 381d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace accounting { 391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 40a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertemplate<size_t kAlignment> 41b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartierclass SpaceBitmap { 42b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier public: 432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers typedef void ScanCallback(mirror::Object* obj, void* finger, void* arg); 442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers typedef void SweepCallback(size_t ptr_count, mirror::Object** ptrs, void* arg); 45b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 4631e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier // Initialize a space bitmap so that it points to a bitmap large enough to cover a heap at 47b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // heap_begin of heap_capacity bytes, where objects are guaranteed to be kAlignment-aligned. 4813735955f39b3b304c37d2b2840663c131262c18Ian Rogers static SpaceBitmap* Create(const std::string& name, uint8_t* heap_begin, size_t heap_capacity); 49b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 5031e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier // Initialize a space bitmap using the provided mem_map as the live bits. Takes ownership of the 5131e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier // mem map. The address range covered starts at heap_begin and is of size equal to heap_capacity. 5231e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier // Objects are kAlignement-aligned. 5331e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier static SpaceBitmap* CreateFromMemMap(const std::string& name, MemMap* mem_map, 5413735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* heap_begin, size_t heap_capacity); 5531e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier 5622d5e735f403c57525fe868304c7123f0ce66399Ian Rogers ~SpaceBitmap(); 57b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 588f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Return the bitmap word index corresponding to memory offset (relative to 598f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // `HeapBegin()`) `offset`. 608f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // See also SpaceBitmap::OffsetBitIndex. 618f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // 62b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // <offset> is the difference from .base to a pointer address. 63b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // <index> is the index of .bits that contains the bit representing 64b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // <offset>. 65be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers static constexpr size_t OffsetToIndex(size_t offset) { 6613735955f39b3b304c37d2b2840663c131262c18Ian Rogers return offset / kAlignment / kBitsPerIntPtrT; 67b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier } 68b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 698f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Return the memory offset (relative to `HeapBegin()`) corresponding to 708f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // bitmap word index `index`. 716f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier template<typename T> 72be2a1df15a31a5223ee9af3015a00c31d2ad2e10Ian Rogers static constexpr T IndexToOffset(T index) { 7313735955f39b3b304c37d2b2840663c131262c18Ian Rogers return static_cast<T>(index * kAlignment * kBitsPerIntPtrT); 74b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier } 75b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 768f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Return the bit within the bitmap word index corresponding to 778f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // memory offset (relative to `HeapBegin()`) `offset`. 788f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // See also SpaceBitmap::OffsetToIndex. 797ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier ALWAYS_INLINE static constexpr uintptr_t OffsetBitIndex(uintptr_t offset) { 807ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier return (offset / kAlignment) % kBitsPerIntPtrT; 817ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier } 827ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier 838f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Return the word-wide bit mask corresponding to `OffsetBitIndex(offset)`. 84cb8aea4bd5e77857c713edeb62bffcb1f7f06a39Andreas Gampe // Bits are packed in the obvious way. 8513735955f39b3b304c37d2b2840663c131262c18Ian Rogers static constexpr uintptr_t OffsetToMask(uintptr_t offset) { 867ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier return static_cast<size_t>(1) << OffsetBitIndex(offset); 87b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier } 88b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 898f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Set the bit corresponding to `obj` in the bitmap and return the previous value of that bit. 90a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier bool Set(const mirror::Object* obj) ALWAYS_INLINE { 91a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier return Modify<true>(obj); 92b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier } 93b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 948f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Clear the bit corresponding to `obj` in the bitmap and return the previous value of that bit. 95a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier bool Clear(const mirror::Object* obj) ALWAYS_INLINE { 96a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier return Modify<false>(obj); 9702b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier } 9802b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier 9902b6a78038f12c109f95eb31713cfc747f5512f1Mathieu Chartier // Returns true if the object was previously marked. 1002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers bool AtomicTestAndSet(const mirror::Object* obj); 101b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 1021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // Fill the bitmap with zeroes. Returns the bitmap's memory to the system as a side-effect. 103b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier void Clear(); 104b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 1058f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Clear a range covered by the bitmap using madvise if possible. 1067ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier void ClearRange(const mirror::Object* begin, const mirror::Object* end); 1077ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier 1088f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Test whether `obj` is part of the bitmap (i.e. return whether the bit 1098f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // corresponding to `obj` has been set in the bitmap). 1108f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // 1118f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Precondition: `obj` is within the range of pointers that this bitmap could 1128f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // potentially cover (i.e. `this->HasAddress(obj)` is true) 1132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers bool Test(const mirror::Object* obj) const; 114b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 115506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers // Return true iff <obj> is within the range of pointers that this bitmap could potentially cover, 116506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers // even if a bit has not been set for it. 117506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers bool HasAddress(const void* obj) const { 118506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers // If obj < heap_begin_ then offset underflows to some very large value past the end of the 119506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers // bitmap. 120cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee const uintptr_t offset = reinterpret_cast<uintptr_t>(obj) - heap_begin_; 121506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers const size_t index = OffsetToIndex(offset); 12213735955f39b3b304c37d2b2840663c131262c18Ian Rogers return index < bitmap_size_ / sizeof(intptr_t); 123506de0cfe98c10b908d2ddb119bbb201542cbfcdIan Rogers } 124b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 125b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier class ClearVisitor { 126b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier public: 127b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier explicit ClearVisitor(SpaceBitmap* const bitmap) 128b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier : bitmap_(bitmap) { 129b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier } 130b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 131df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom void operator()(mirror::Object* obj) const { 132b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier bitmap_->Clear(obj); 133b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier } 134b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier private: 135b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier SpaceBitmap* const bitmap_; 136b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier }; 137b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 138b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier template <typename Visitor> 139b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier void VisitRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const { 140df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom for (; visit_begin < visit_end; visit_begin += kAlignment) { 1412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers visitor(reinterpret_cast<mirror::Object*>(visit_begin)); 142b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier } 143b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier } 144b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 145e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier // Visit the live objects in the range [visit_begin, visit_end). 146e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier // TODO: Use lock annotations when clang is fixed. 147bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe // REQUIRES(Locks::heap_bitmap_lock_) REQUIRES_SHARED(Locks::mutator_lock_); 148184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier template <typename Visitor> 149351c44765279142d15333e2ae02b8a423d195b1bAndreas Gampe void VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end, Visitor&& visitor) const 150e9ea70bb806f7c1dcd57efb6f48f1d6329d5f103Mathieu Chartier NO_THREAD_SAFETY_ANALYSIS; 151b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 152a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier // Visits set bits in address order. The callback is not permitted to change the bitmap bits or 153a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier // max during the traversal. 1540c18338ebae6b3597c882887f8354b64abb5e90fAndreas Gampe template <typename Visitor> 1550c18338ebae6b3597c882887f8354b64abb5e90fAndreas Gampe void Walk(Visitor&& visitor) 1560c18338ebae6b3597c882887f8354b64abb5e90fAndreas Gampe REQUIRES_SHARED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); 157b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 158a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier // Walk through the bitmaps in increasing address order, and find the object pointers that 159a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier // correspond to garbage objects. Call <callback> zero or more times with lists of these object 160a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier // pointers. The callback is not permitted to increase the max of either bitmap. 161184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier static void SweepWalk(const SpaceBitmap& live, const SpaceBitmap& mark, uintptr_t base, 162184e322fe8ddd75c844a1eb2eb1ca32bc02f2d45Mathieu Chartier uintptr_t max, SweepCallback* thunk, void* arg); 163b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 164357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier void CopyFrom(SpaceBitmap* source_bitmap); 165357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier 166cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier // Starting address of our internal storage. 167c381c36aacf977f7e314e6a91e47b31b04639f62Mathieu Chartier Atomic<uintptr_t>* Begin() { 168cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier return bitmap_begin_; 169cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier } 170cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier 171cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier // Size of our internal storage 172cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier size_t Size() const { 173cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier return bitmap_size_; 174cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier } 175cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier 176cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier // Size in bytes of the memory that the bitmaps spans. 1776f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier uint64_t HeapSize() const { 17813735955f39b3b304c37d2b2840663c131262c18Ian Rogers return IndexToOffset<uint64_t>(Size() / sizeof(intptr_t)); 179cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier } 180cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier 181379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier void SetHeapSize(size_t bytes) { 182379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier // TODO: Un-map the end of the mem map. 1832a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier heap_limit_ = heap_begin_ + bytes; 184379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier bitmap_size_ = OffsetToIndex(bytes) * sizeof(intptr_t); 185379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier CHECK_EQ(HeapSize(), bytes); 186379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier } 187379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier 188dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier uintptr_t HeapBegin() const { 189cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier return heap_begin_; 190cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier } 191cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier 192dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier // The maximum address which the bitmap can span. (HeapBegin() <= object < HeapLimit()). 1936f365cc033654a5a3b45eaa1379d4b5f156b0ceeMathieu Chartier uint64_t HeapLimit() const { 1942a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier return heap_limit_; 195dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier } 196dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier 197dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier // Set the max address which can covered by the bitmap. 198dcf8d7283bd51714f3faa55b631ae4103dc98b51Mathieu Chartier void SetHeapLimit(uintptr_t new_end); 199cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier 200a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier std::string GetName() const { 201a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier return name_; 202a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier } 203a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier 204a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier void SetName(const std::string& name) { 205a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier name_ = name; 206a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier } 207357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier 208576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogers std::string Dump() const; 2091d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 210d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier // Helper function for computing bitmap size based on a 64 bit capacity. 211d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier static size_t ComputeBitmapSize(uint64_t capacity); 212d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier static size_t ComputeHeapSize(uint64_t bitmap_bytes); 213d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier 214b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier private: 215b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1, 216b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // however, we document that this is expected on heap_end_ 2172a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier SpaceBitmap(const std::string& name, 2182a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier MemMap* mem_map, 2192a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier uintptr_t* bitmap_begin, 2202a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier size_t bitmap_size, 2212a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier const void* heap_begin, 2222a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier size_t heap_capacity); 223b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 2248f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // Change the value of the bit corresponding to `obj` in the bitmap 2258f7ea9ab1703ef52c0c5ca3490e2913ac67f2a16Roland Levillain // to `kSetBit` and return the previous value of that bit. 226a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier template<bool kSetBit> 227a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier bool Modify(const mirror::Object* obj); 228a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier 229b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // Backing storage for bitmap. 230700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<MemMap> mem_map_; 231b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 232b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // This bitmap itself, word sized for efficiency in scanning. 233c381c36aacf977f7e314e6a91e47b31b04639f62Mathieu Chartier Atomic<uintptr_t>* const bitmap_begin_; 234b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 235b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // Size of this bitmap. 236cc236d74772dda5a4161d9bc5f497fd3d956eb87Mathieu Chartier size_t bitmap_size_; 237b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 2382a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier // The start address of the memory covered by the bitmap, which corresponds to the word 2392a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier // containing the first bit in the bitmap. 240b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier const uintptr_t heap_begin_; 241b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 2422a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier // The end address of the memory covered by the bitmap. This may not be on a word boundary. 2432a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier uintptr_t heap_limit_; 2442a1513bdb0a3ecac628cd5620420d66c28413f1eMathieu Chartier 245b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier // Name of this bitmap. 246b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier std::string name_; 247b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier}; 248b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 249a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertypedef SpaceBitmap<kObjectAlignment> ContinuousSpaceBitmap; 250a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertypedef SpaceBitmap<kLargeObjectAlignment> LargeObjectBitmap; 251a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier 252a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartiertemplate<size_t kAlignment> 253a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartierstd::ostream& operator << (std::ostream& stream, const SpaceBitmap<kAlignment>& bitmap); 254357e9be24c17a6bc2ae9fb53f25c73503116101dMathieu Chartier 2551d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace accounting 2561d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace gc 257b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier} // namespace art 258b062fdd4cb097fbae69b4bcb479c34d83ecab8caMathieu Chartier 259fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_ 260