12cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi/* 22cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * Copyright (C) 2014 The Android Open Source Project 32cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * 42cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * Licensed under the Apache License, Version 2.0 (the "License"); 52cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * you may not use this file except in compliance with the License. 62cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * You may obtain a copy of the License at 72cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * 82cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * http://www.apache.org/licenses/LICENSE-2.0 92cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * 102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * Unless required by applicable law or agreed to in writing, software 112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * distributed under the License is distributed on an "AS IS" BASIS, 122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * See the License for the specific language governing permissions and 142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi * limitations under the License. 152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi */ 162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#ifndef ART_RUNTIME_GC_SPACE_REGION_SPACE_H_ 182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#define ART_RUNTIME_GC_SPACE_REGION_SPACE_H_ 192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 20d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi#include "gc/accounting/read_barrier_table.h" 212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#include "object_callbacks.h" 222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#include "space.h" 23d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi#include "thread.h" 242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchinamespace art { 262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchinamespace gc { 272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchinamespace space { 282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi// A space that consists of equal-sized regions. 302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiclass RegionSpace FINAL : public ContinuousMemMapAllocSpace { 312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi public: 322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi typedef void(*WalkCallback)(void *start, void *end, size_t num_bytes, void* callback_arg); 332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SpaceType GetType() const OVERRIDE { 352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return kSpaceTypeRegionSpace; 362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 383c3c4a1da1e8c03e78813d175a9974fb9f1097eaHiroshi Yamauchi // Create a region space mem map with the requested sizes. The requested base address is not 392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // guaranteed to be granted, if it is required, the caller should call Begin on the returned 402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // space to confirm the request was granted. 413c3c4a1da1e8c03e78813d175a9974fb9f1097eaHiroshi Yamauchi static MemMap* CreateMemMap(const std::string& name, size_t capacity, uint8_t* requested_begin); 423c3c4a1da1e8c03e78813d175a9974fb9f1097eaHiroshi Yamauchi static RegionSpace* Create(const std::string& name, MemMap* mem_map); 432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 442cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Allocate num_bytes, returns null if the space is full. 452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated, 4690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier size_t* usable_size, size_t* bytes_tl_bulk_allocated) 4790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE REQUIRES(!region_lock_); 482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Thread-unsafe allocation for when mutators are suspended, used by the semispace collector. 492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* AllocThreadUnsafe(Thread* self, size_t num_bytes, size_t* bytes_allocated, 504460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, size_t* bytes_tl_bulk_allocated) 5190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE REQUIRES(Locks::mutator_lock_) REQUIRES(!region_lock_); 522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // The main allocation routine. 532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<bool kForEvac> 542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ALWAYS_INLINE mirror::Object* AllocNonvirtual(size_t num_bytes, size_t* bytes_allocated, 554460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, 5690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier size_t* bytes_tl_bulk_allocated) 5790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!region_lock_); 582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Allocate/free large objects (objects that are larger than the region size.) 592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<bool kForEvac> 604460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi mirror::Object* AllocLarge(size_t num_bytes, size_t* bytes_allocated, size_t* usable_size, 6190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier size_t* bytes_tl_bulk_allocated) REQUIRES(!region_lock_); 6290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void FreeLarge(mirror::Object* large_obj, size_t bytes_allocated) REQUIRES(!region_lock_); 632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Return the storage space required by obj. 652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t AllocationSize(mirror::Object* obj, size_t* usable_size) OVERRIDE 66bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!region_lock_) { 672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return AllocationSizeNonvirtual(obj, usable_size); 682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size) 70bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!region_lock_); 712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t Free(Thread*, mirror::Object*) OVERRIDE { 732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi UNIMPLEMENTED(FATAL); 742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t FreeList(Thread*, size_t, mirror::Object**) OVERRIDE { 772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi UNIMPLEMENTED(FATAL); 782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi accounting::ContinuousSpaceBitmap* GetLiveBitmap() const OVERRIDE { 817ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier return mark_bitmap_.get(); 822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi accounting::ContinuousSpaceBitmap* GetMarkBitmap() const OVERRIDE { 847ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier return mark_bitmap_.get(); 852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 8790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void Clear() OVERRIDE REQUIRES(!region_lock_); 882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Dump(std::ostream& os) const; 9090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void DumpRegions(std::ostream& os) REQUIRES(!region_lock_); 9190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void DumpNonFreeRegions(std::ostream& os) REQUIRES(!region_lock_); 922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 9390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier size_t RevokeThreadLocalBuffers(Thread* thread) REQUIRES(!region_lock_); 9490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void RevokeThreadLocalBuffersLocked(Thread* thread) REQUIRES(region_lock_); 9590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier size_t RevokeAllThreadLocalBuffers() 9690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::runtime_shutdown_lock_, !Locks::thread_list_lock_, !region_lock_); 9790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void AssertThreadLocalBuffersAreRevoked(Thread* thread) REQUIRES(!region_lock_); 9890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void AssertAllThreadLocalBuffersAreRevoked() 9990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::runtime_shutdown_lock_, !Locks::thread_list_lock_, !region_lock_); 1002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 101d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi enum class RegionType : uint8_t { 102d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeAll, // All types. 103d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeFromSpace, // From-space. To be evacuated. 104d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeUnevacFromSpace, // Unevacuated from-space. Not to be evacuated. 105d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeToSpace, // To-space. 106d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeNone, // None. 107d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi }; 108d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 109d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi enum class RegionState : uint8_t { 110d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionStateFree, // Free region. 111d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionStateAllocated, // Allocated region. 112d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionStateLarge, // Large allocated (allocation larger than the region size). 113d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionStateLargeTail, // Large tail (non-first regions of a large allocation). 1142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi }; 1152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 11690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier template<RegionType kRegionType> uint64_t GetBytesAllocatedInternal() REQUIRES(!region_lock_); 11790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier template<RegionType kRegionType> uint64_t GetObjectsAllocatedInternal() REQUIRES(!region_lock_); 11890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint64_t GetBytesAllocated() REQUIRES(!region_lock_) { 119d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetBytesAllocatedInternal<RegionType::kRegionTypeAll>(); 1202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 12190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint64_t GetObjectsAllocated() REQUIRES(!region_lock_) { 122d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetObjectsAllocatedInternal<RegionType::kRegionTypeAll>(); 1232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 12490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint64_t GetBytesAllocatedInFromSpace() REQUIRES(!region_lock_) { 125d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetBytesAllocatedInternal<RegionType::kRegionTypeFromSpace>(); 1262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 12790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint64_t GetObjectsAllocatedInFromSpace() REQUIRES(!region_lock_) { 128d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetObjectsAllocatedInternal<RegionType::kRegionTypeFromSpace>(); 1292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 13090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint64_t GetBytesAllocatedInUnevacFromSpace() REQUIRES(!region_lock_) { 131d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetBytesAllocatedInternal<RegionType::kRegionTypeUnevacFromSpace>(); 1322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 13390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint64_t GetObjectsAllocatedInUnevacFromSpace() REQUIRES(!region_lock_) { 134d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetObjectsAllocatedInternal<RegionType::kRegionTypeUnevacFromSpace>(); 1352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool CanMoveObjects() const OVERRIDE { 1382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return true; 1392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool Contains(const mirror::Object* obj) const { 1422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi const uint8_t* byte_obj = reinterpret_cast<const uint8_t*>(obj); 1432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return byte_obj >= Begin() && byte_obj < Limit(); 1442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi RegionSpace* AsRegionSpace() OVERRIDE { 1472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return this; 1482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Go through all of the blocks and visit the continuous objects. 1512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Walk(ObjectCallback* callback, void* arg) 15290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(Locks::mutator_lock_) { 1532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi WalkInternal<false>(callback, arg); 1542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void WalkToSpace(ObjectCallback* callback, void* arg) 15790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(Locks::mutator_lock_) { 1582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi WalkInternal<true>(callback, arg); 1592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi accounting::ContinuousSpaceBitmap::SweepCallback* GetSweepCallback() OVERRIDE { 1622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return nullptr; 1632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) OVERRIDE 165bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!region_lock_); 1662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Object alignment within the space. 1682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi static constexpr size_t kAlignment = kObjectAlignment; 1692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // The region size. 1706711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi static constexpr size_t kRegionSize = 256 * KB; 1712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInFromSpace(mirror::Object* ref) { 1732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (HasAddress(ref)) { 1742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 1752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return r->IsInFromSpace(); 1762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return false; 1782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 180a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier bool IsInNewlyAllocatedRegion(mirror::Object* ref) { 181a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier if (HasAddress(ref)) { 182a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier Region* r = RefToRegionUnlocked(ref); 183a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier return r->IsNewlyAllocated(); 184a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier } 185a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier return false; 186a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier } 187a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier 1882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInUnevacFromSpace(mirror::Object* ref) { 1892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (HasAddress(ref)) { 1902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 1912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return r->IsInUnevacFromSpace(); 1922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return false; 1942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInToSpace(mirror::Object* ref) { 1972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (HasAddress(ref)) { 1982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 1992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return r->IsInToSpace(); 2002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return false; 2022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 204d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi RegionType GetRegionType(mirror::Object* ref) { 205d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi if (HasAddress(ref)) { 206d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 207d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return r->Type(); 208d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 209d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return RegionType::kRegionTypeNone; 210d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 211d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 2122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetFromSpace(accounting::ReadBarrierTable* rb_table, bool force_evacuate_all) 21390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!region_lock_); 2142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 21590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier size_t FromSpaceSize() REQUIRES(!region_lock_); 21690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier size_t UnevacFromSpaceSize() REQUIRES(!region_lock_); 21790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier size_t ToSpaceSize() REQUIRES(!region_lock_); 218371b04724522c5acbb76878e5825a308ef065f32Mathieu Chartier void ClearFromSpace(uint64_t* cleared_bytes, uint64_t* cleared_objects) REQUIRES(!region_lock_); 2192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AddLiveBytes(mirror::Object* ref, size_t alloc_size) { 221d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi Region* reg = RefToRegionUnlocked(ref); 2222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi reg->AddLiveBytes(alloc_size); 2232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2258e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi void AssertAllRegionLiveBytesZeroOrCleared() REQUIRES(!region_lock_) { 2268e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi if (kIsDebugBuild) { 2278e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi MutexLock mu(Thread::Current(), region_lock_); 2288e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi for (size_t i = 0; i < num_regions_; ++i) { 2298e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi Region* r = ®ions_[i]; 2308e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi size_t live_bytes = r->LiveBytes(); 2318e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi CHECK(live_bytes == 0U || live_bytes == static_cast<size_t>(-1)) << live_bytes; 2328e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi } 2338e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi } 2348e67465aa57ee58425be8812c8dba2f7f59cdc2eHiroshi Yamauchi } 2352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 23690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void RecordAlloc(mirror::Object* ref) REQUIRES(!region_lock_); 237bf48003fa32d2845f2213c0ba31af6677715662dMathieu Chartier bool AllocNewTlab(Thread* self, size_t min_bytes) REQUIRES(!region_lock_); 2382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint32_t Time() { 2402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return time_; 2412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi private: 2442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi RegionSpace(const std::string& name, MemMap* mem_map); 2452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<bool kToSpaceOnly> 2472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void WalkInternal(ObjectCallback* callback, void* arg) NO_THREAD_SAFETY_ANALYSIS; 2482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi class Region { 2502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi public: 2512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region() 2522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi : idx_(static_cast<size_t>(-1)), 253d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi begin_(nullptr), top_(nullptr), end_(nullptr), 254d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_(RegionState::kRegionStateAllocated), type_(RegionType::kRegionTypeToSpace), 2552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi objects_allocated_(0), alloc_time_(0), live_bytes_(static_cast<size_t>(-1)), 2562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_(false), is_a_tlab_(false), thread_(nullptr) {} 2572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 25822c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier void Init(size_t idx, uint8_t* begin, uint8_t* end) { 25922c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier idx_ = idx; 26022c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier begin_ = begin; 26122c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier top_.StoreRelaxed(begin); 26222c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier end_ = end; 26322c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier state_ = RegionState::kRegionStateFree; 26422c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier type_ = RegionType::kRegionTypeNone; 26522c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier objects_allocated_.StoreRelaxed(0); 26622c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier alloc_time_ = 0; 26722c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier live_bytes_ = static_cast<size_t>(-1); 26822c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier is_newly_allocated_ = false; 26922c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier is_a_tlab_ = false; 27022c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier thread_ = nullptr; 2712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(begin, end); 2722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(static_cast<size_t>(end - begin), kRegionSize); 2732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 275d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi RegionState State() const { 276d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return state_; 277d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 278d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 279d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi RegionType Type() const { 280d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_; 281d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 282d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 2831f0dc6f98833ece47617e45e3ad9689f4b248b80Mathieu Chartier void Clear(bool zero_and_release_pages) { 28422c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier top_.StoreRelaxed(begin_); 285d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_ = RegionState::kRegionStateFree; 286d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeNone; 28722c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier objects_allocated_.StoreRelaxed(0); 2882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = 0; 2892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ = static_cast<size_t>(-1); 2901f0dc6f98833ece47617e45e3ad9689f4b248b80Mathieu Chartier if (zero_and_release_pages) { 2911f0dc6f98833ece47617e45e3ad9689f4b248b80Mathieu Chartier ZeroAndReleasePages(begin_, end_ - begin_); 2921f0dc6f98833ece47617e45e3ad9689f4b248b80Mathieu Chartier } 2932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_ = false; 2942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_a_tlab_ = false; 2952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi thread_ = nullptr; 2962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ALWAYS_INLINE mirror::Object* Alloc(size_t num_bytes, size_t* bytes_allocated, 2994460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, 3004460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated); 3012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsFree() const { 303d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool is_free = state_ == RegionState::kRegionStateFree; 3042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (is_free) { 305d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(IsInNoSpace()); 30622c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier DCHECK_EQ(begin_, Top()); 30722c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier DCHECK_EQ(objects_allocated_.LoadRelaxed(), 0U); 3082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return is_free; 3102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Given a free region, declare it non-free (allocated). 3136711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi void Unfree(RegionSpace* region_space, uint32_t alloc_time) 3146711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi REQUIRES(region_space->region_lock_) { 3152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsFree()); 316d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_ = RegionState::kRegionStateAllocated; 317d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeToSpace; 3182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = alloc_time; 3196711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi region_space->AdjustNonFreeRegionLimit(idx_); 3202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3226711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi void UnfreeLarge(RegionSpace* region_space, uint32_t alloc_time) 3236711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi REQUIRES(region_space->region_lock_) { 3242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsFree()); 325d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_ = RegionState::kRegionStateLarge; 326d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeToSpace; 3272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = alloc_time; 3286711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi region_space->AdjustNonFreeRegionLimit(idx_); 3292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3316711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi void UnfreeLargeTail(RegionSpace* region_space, uint32_t alloc_time) 3326711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi REQUIRES(region_space->region_lock_) { 3332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsFree()); 334d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_ = RegionState::kRegionStateLargeTail; 335d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeToSpace; 3362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = alloc_time; 3376711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi region_space->AdjustNonFreeRegionLimit(idx_); 3382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetNewlyAllocated() { 3412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_ = true; 3422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 344d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi // Non-large, non-large-tail allocated. 345d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool IsAllocated() const { 346d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return state_ == RegionState::kRegionStateAllocated; 3472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 349d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi // Large allocated. 3502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsLarge() const { 351d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool is_large = state_ == RegionState::kRegionStateLarge; 3522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (is_large) { 3536711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi DCHECK_LT(begin_ + kRegionSize, Top()); 3542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return is_large; 3562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 358d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi // Large-tail allocated. 3592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsLargeTail() const { 360d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool is_large_tail = state_ == RegionState::kRegionStateLargeTail; 3612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (is_large_tail) { 36222c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier DCHECK_EQ(begin_, Top()); 3632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return is_large_tail; 3652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t Idx() const { 3682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return idx_; 3692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 371a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier bool IsNewlyAllocated() const { 372a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier return is_newly_allocated_; 373a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier } 374a1467d07c4c1e838ff5c07a4ff4ec35aab6a701fMathieu Chartier 3752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInFromSpace() const { 376d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_ == RegionType::kRegionTypeFromSpace; 3772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInToSpace() const { 380d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_ == RegionType::kRegionTypeToSpace; 3812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInUnevacFromSpace() const { 384d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_ == RegionType::kRegionTypeUnevacFromSpace; 385d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 386d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 387d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool IsInNoSpace() const { 388d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_ == RegionType::kRegionTypeNone; 3892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetAsFromSpace() { 392d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(!IsFree() && IsInToSpace()); 393d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeFromSpace; 3942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ = static_cast<size_t>(-1); 3952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetAsUnevacFromSpace() { 398d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(!IsFree() && IsInToSpace()); 399d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeUnevacFromSpace; 4002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ = 0U; 4012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetUnevacFromSpaceAsToSpace() { 404d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(!IsFree() && IsInUnevacFromSpace()); 405d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeToSpace; 4062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ALWAYS_INLINE bool ShouldBeEvacuated(); 4092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AddLiveBytes(size_t live_bytes) { 4112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsInUnevacFromSpace()); 4122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(!IsLargeTail()); 4132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_NE(live_bytes_, static_cast<size_t>(-1)); 4142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ += live_bytes; 4152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(live_bytes_, BytesAllocated()); 4162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t LiveBytes() const { 4192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return live_bytes_; 4202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 422bf48003fa32d2845f2213c0ba31af6677715662dMathieu Chartier size_t BytesAllocated() const; 4232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t ObjectsAllocated() const { 4252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (IsLarge()) { 4266711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi DCHECK_LT(begin_ + kRegionSize, Top()); 42722c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier DCHECK_EQ(objects_allocated_.LoadRelaxed(), 0U); 4282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 1; 4292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else if (IsLargeTail()) { 43022c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier DCHECK_EQ(begin_, Top()); 43122c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier DCHECK_EQ(objects_allocated_.LoadRelaxed(), 0U); 4322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 4332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else { 434d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(IsAllocated()) << static_cast<uint>(state_); 4352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return objects_allocated_; 4362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* Begin() const { 4402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return begin_; 4412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 44322c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier ALWAYS_INLINE uint8_t* Top() const { 44422c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier return top_.LoadRelaxed(); 4452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetTop(uint8_t* new_top) { 44822c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier top_.StoreRelaxed(new_top); 4492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* End() const { 4522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return end_; 4532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool Contains(mirror::Object* ref) const { 4562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return begin_ <= reinterpret_cast<uint8_t*>(ref) && reinterpret_cast<uint8_t*>(ref) < end_; 4572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Dump(std::ostream& os) const; 4602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void RecordThreadLocalAllocations(size_t num_objects, size_t num_bytes) { 462d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(IsAllocated()); 46322c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier DCHECK_EQ(objects_allocated_.LoadRelaxed(), 0U); 46422c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier DCHECK_EQ(Top(), end_); 46522c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier objects_allocated_.StoreRelaxed(num_objects); 46622c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier top_.StoreRelaxed(begin_ + num_bytes); 467bf48003fa32d2845f2213c0ba31af6677715662dMathieu Chartier DCHECK_LE(Top(), end_); 4682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi private: 47122c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier size_t idx_; // The region's index in the region space. 47222c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier uint8_t* begin_; // The begin address of the region. 47322c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier Atomic<uint8_t*> top_; // The current position of the allocation. 47422c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier uint8_t* end_; // The end address of the region. 47522c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier RegionState state_; // The region state (see RegionState). 47622c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier RegionType type_; // The region type (see RegionType). 47722c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier Atomic<size_t> objects_allocated_; // The number of objects allocated. 47822c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier uint32_t alloc_time_; // The allocation time of the region. 47922c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier size_t live_bytes_; // The live bytes. Used to compute the live percent. 48022c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier bool is_newly_allocated_; // True if it's allocated after the last collection. 48122c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier bool is_a_tlab_; // True if it's a tlab. 48222c8e40d4d7c46867cf67462319503640167a125Mathieu Chartier Thread* thread_; // The owning thread if it's a tlab. 4832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi friend class RegionSpace; 4852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi }; 4862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 48790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier Region* RefToRegion(mirror::Object* ref) REQUIRES(!region_lock_) { 4882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi MutexLock mu(Thread::Current(), region_lock_); 4892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return RefToRegionLocked(ref); 4902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* RefToRegionUnlocked(mirror::Object* ref) NO_THREAD_SAFETY_ANALYSIS { 4932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // For a performance reason (this is frequently called via 4942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // IsInFromSpace() etc.) we avoid taking a lock here. Note that 4952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // since we only change a region from to-space to from-space only 4962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // during a pause (SetFromSpace()) and from from-space to free 4972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // (after GC is done) as long as ref is a valid reference into an 4982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // allocated region, it's safe to access the region state without 4992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // the lock. 5002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return RefToRegionLocked(ref); 5012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 5022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 50390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier Region* RefToRegionLocked(mirror::Object* ref) REQUIRES(region_lock_) { 5042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(HasAddress(ref)); 5052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uintptr_t offset = reinterpret_cast<uintptr_t>(ref) - reinterpret_cast<uintptr_t>(Begin()); 5062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t reg_idx = offset / kRegionSize; 5072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(reg_idx, num_regions_); 5082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* reg = ®ions_[reg_idx]; 5092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(reg->Idx(), reg_idx); 5102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(reg->Contains(ref)); 5112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return reg; 5122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 5132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* GetNextObject(mirror::Object* obj) 515bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_); 5162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5176711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi void AdjustNonFreeRegionLimit(size_t new_non_free_region_index) REQUIRES(region_lock_) { 5186711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi DCHECK_LT(new_non_free_region_index, num_regions_); 5196711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi non_free_region_index_limit_ = std::max(non_free_region_index_limit_, 5206711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi new_non_free_region_index + 1); 5216711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi VerifyNonFreeRegionLimit(); 5226711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi } 5236711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi 5246711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi void SetNonFreeRegionLimit(size_t new_non_free_region_index_limit) REQUIRES(region_lock_) { 5256711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi DCHECK_LE(new_non_free_region_index_limit, num_regions_); 5266711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi non_free_region_index_limit_ = new_non_free_region_index_limit; 5276711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi VerifyNonFreeRegionLimit(); 5286711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi } 5296711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi 5306711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi void VerifyNonFreeRegionLimit() REQUIRES(region_lock_) { 5316711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi if (kIsDebugBuild && non_free_region_index_limit_ < num_regions_) { 5326711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi for (size_t i = non_free_region_index_limit_; i < num_regions_; ++i) { 5336711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi CHECK(regions_[i].IsFree()); 5346711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi } 5356711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi } 5366711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi } 5376711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi 5382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Mutex region_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 5392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint32_t time_; // The time as the number of collections since the startup. 5412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t num_regions_; // The number of regions in this space. 5422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t num_non_free_regions_; // The number of non-free regions in this space. 5432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi std::unique_ptr<Region[]> regions_ GUARDED_BY(region_lock_); 5442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // The pointer to the region array. 5456711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi // The upper-bound index of the non-free regions. Used to avoid scanning all regions in 5466711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi // SetFromSpace(). Invariant: for all i >= non_free_region_index_limit_, regions_[i].IsFree() is 5476711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi // true. 5486711cd8bc9f9053d653a52676177f8a29c1c36ebHiroshi Yamauchi size_t non_free_region_index_limit_ GUARDED_BY(region_lock_); 5492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* current_region_; // The region that's being allocated currently. 5502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* evac_region_; // The region that's being evacuated to currently. 5512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region full_region_; // The dummy/sentinel region that looks full. 5522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5537ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier // Mark bitmap used by the GC. 5547ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier std::unique_ptr<accounting::ContinuousSpaceBitmap> mark_bitmap_; 5557ec38dcb84d61f6172bbb5a303bd5ab7139f7409Mathieu Chartier 5562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DISALLOW_COPY_AND_ASSIGN(RegionSpace); 5572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi}; 5582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 559d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchistd::ostream& operator<<(std::ostream& os, const RegionSpace::RegionState& value); 560d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchistd::ostream& operator<<(std::ostream& os, const RegionSpace::RegionType& value); 561d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 5622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} // namespace space 5632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} // namespace gc 5642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} // namespace art 5652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#endif // ART_RUNTIME_GC_SPACE_REGION_SPACE_H_ 567