region_space.h revision 2cd334ae2d4287216523882f0d298cf3901b7ab1
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 202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#include "object_callbacks.h" 212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#include "space.h" 222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#include "gc/accounting/read_barrier_table.h" 232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchinamespace art { 252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchinamespace gc { 262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchinamespace space { 272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi// A space that consists of equal-sized regions. 292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiclass RegionSpace FINAL : public ContinuousMemMapAllocSpace { 302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi public: 312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi typedef void(*WalkCallback)(void *start, void *end, size_t num_bytes, void* callback_arg); 322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SpaceType GetType() const OVERRIDE { 342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return kSpaceTypeRegionSpace; 352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Create a region space with the requested sizes. The requested base address is not 382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // guaranteed to be granted, if it is required, the caller should call Begin on the returned 392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // space to confirm the request was granted. 402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi static RegionSpace* Create(const std::string& name, size_t capacity, uint8_t* requested_begin); 412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Allocate num_bytes, returns nullptr if the space is full. 432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated, 442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t* usable_size) OVERRIDE; 452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Thread-unsafe allocation for when mutators are suspended, used by the semispace collector. 462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* AllocThreadUnsafe(Thread* self, size_t num_bytes, size_t* bytes_allocated, 472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t* usable_size) 482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi OVERRIDE EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_); 492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // The main allocation routine. 502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<bool kForEvac> 512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ALWAYS_INLINE mirror::Object* AllocNonvirtual(size_t num_bytes, size_t* bytes_allocated, 522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t* usable_size); 532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Allocate/free large objects (objects that are larger than the region size.) 542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<bool kForEvac> 552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* AllocLarge(size_t num_bytes, size_t* bytes_allocated, size_t* usable_size); 562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void FreeLarge(mirror::Object* large_obj, size_t bytes_allocated); 572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Return the storage space required by obj. 592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t AllocationSize(mirror::Object* obj, size_t* usable_size) OVERRIDE 602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return AllocationSizeNonvirtual(obj, usable_size); 622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size) 642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t Free(Thread*, mirror::Object*) OVERRIDE { 672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi UNIMPLEMENTED(FATAL); 682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t FreeList(Thread*, size_t, mirror::Object**) OVERRIDE { 712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi UNIMPLEMENTED(FATAL); 722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi accounting::ContinuousSpaceBitmap* GetLiveBitmap() const OVERRIDE { 752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // No live bitmap. 762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return nullptr; 772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi accounting::ContinuousSpaceBitmap* GetMarkBitmap() const OVERRIDE { 792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // No mark bitmap. 802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return nullptr; 812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Clear() OVERRIDE LOCKS_EXCLUDED(region_lock_); 842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Dump(std::ostream& os) const; 862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void DumpRegions(std::ostream& os); 872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void DumpNonFreeRegions(std::ostream& os); 882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void RevokeThreadLocalBuffers(Thread* thread) LOCKS_EXCLUDED(region_lock_); 902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void RevokeThreadLocalBuffersLocked(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(region_lock_); 912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void RevokeAllThreadLocalBuffers() LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_, 922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Locks::thread_list_lock_); 932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AssertThreadLocalBuffersAreRevoked(Thread* thread) LOCKS_EXCLUDED(region_lock_); 942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AssertAllThreadLocalBuffersAreRevoked() LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_, 952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Locks::thread_list_lock_); 962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi enum SubSpaceType { 982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kAllSpaces, // All spaces. 992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kFromSpace, // From-space. To be evacuated. 1002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kUnevacFromSpace, // Unevacuated from-space. Not to be evacuated. 1012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kToSpace, // To-space. 1022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi }; 1032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<SubSpaceType kSubSpaceType> uint64_t GetBytesAllocatedInternal(); 1052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<SubSpaceType kSubSpaceType> uint64_t GetObjectsAllocatedInternal(); 1062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetBytesAllocated() { 1072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return GetBytesAllocatedInternal<kAllSpaces>(); 1082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetObjectsAllocated() { 1102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return GetObjectsAllocatedInternal<kAllSpaces>(); 1112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetBytesAllocatedInFromSpace() { 1132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return GetBytesAllocatedInternal<kFromSpace>(); 1142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetObjectsAllocatedInFromSpace() { 1162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return GetObjectsAllocatedInternal<kFromSpace>(); 1172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetBytesAllocatedInUnevacFromSpace() { 1192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return GetBytesAllocatedInternal<kUnevacFromSpace>(); 1202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetObjectsAllocatedInUnevacFromSpace() { 1222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return GetObjectsAllocatedInternal<kUnevacFromSpace>(); 1232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool CanMoveObjects() const OVERRIDE { 1262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return true; 1272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool Contains(const mirror::Object* obj) const { 1302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi const uint8_t* byte_obj = reinterpret_cast<const uint8_t*>(obj); 1312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return byte_obj >= Begin() && byte_obj < Limit(); 1322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi RegionSpace* AsRegionSpace() OVERRIDE { 1352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return this; 1362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Go through all of the blocks and visit the continuous objects. 1392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Walk(ObjectCallback* callback, void* arg) 1402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 1412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi WalkInternal<false>(callback, arg); 1422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void WalkToSpace(ObjectCallback* callback, void* arg) 1452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 1462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi WalkInternal<true>(callback, arg); 1472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi accounting::ContinuousSpaceBitmap::SweepCallback* GetSweepCallback() OVERRIDE { 1502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return nullptr; 1512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) OVERRIDE 1532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Object alignment within the space. 1562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi static constexpr size_t kAlignment = kObjectAlignment; 1572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // The region size. 1582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi static constexpr size_t kRegionSize = 1 * MB; 1592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInFromSpace(mirror::Object* ref) { 1612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (HasAddress(ref)) { 1622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 1632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return r->IsInFromSpace(); 1642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return false; 1662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInUnevacFromSpace(mirror::Object* ref) { 1692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (HasAddress(ref)) { 1702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 1712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return r->IsInUnevacFromSpace(); 1722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return false; 1742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInToSpace(mirror::Object* ref) { 1772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (HasAddress(ref)) { 1782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 1792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return r->IsInToSpace(); 1802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return false; 1822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetFromSpace(accounting::ReadBarrierTable* rb_table, bool force_evacuate_all) 1852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi LOCKS_EXCLUDED(region_lock_); 1862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t FromSpaceSize(); 1882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t UnevacFromSpaceSize(); 1892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t ToSpaceSize(); 1902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void ClearFromSpace(); 1912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AddLiveBytes(mirror::Object* ref, size_t alloc_size) { 1932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* reg = RefToRegion(ref); 1942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi reg->AddLiveBytes(alloc_size); 1952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AssertAllRegionLiveBytesZeroOrCleared(); 1982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void RecordAlloc(mirror::Object* ref); 2002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool AllocNewTlab(Thread* self); 2012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint32_t Time() { 2032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return time_; 2042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi private: 2072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi RegionSpace(const std::string& name, MemMap* mem_map); 2082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<bool kToSpaceOnly> 2102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void WalkInternal(ObjectCallback* callback, void* arg) NO_THREAD_SAFETY_ANALYSIS; 2112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi enum RegionState { 2132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionFree, // Free region. 2142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionToSpace, // To-space region. 2152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionFromSpace, // From-space region. To be evacuated. 2162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionUnevacFromSpace, // Unevacuated from-space region. Not to be evacuated. 2172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionLargeToSpace, // Large (allocation larger than the region size) to-space. 2182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionLargeFromSpace, // Large from-space. To be evacuated. 2192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionLargeUnevacFromSpace, // Large unevacuated from-space. 2202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionLargeTailToSpace, // Large tail (non-first regions of a large allocation). 2212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionLargeTailFromSpace, // Large tail from-space. 2222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kRegionLargeTailUnevacFromSpace, // Large tail unevacuated from-space. 2232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi }; 2242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi class Region { 2262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi public: 2272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region() 2282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi : idx_(static_cast<size_t>(-1)), 2292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi begin_(nullptr), top_(nullptr), end_(nullptr), state_(kRegionToSpace), 2302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi objects_allocated_(0), alloc_time_(0), live_bytes_(static_cast<size_t>(-1)), 2312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_(false), is_a_tlab_(false), thread_(nullptr) {} 2322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region(size_t idx, uint8_t* begin, uint8_t* end) 2342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi : idx_(idx), begin_(begin), top_(begin), end_(end), state_(kRegionFree), 2352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi objects_allocated_(0), alloc_time_(0), live_bytes_(static_cast<size_t>(-1)), 2362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_(false), is_a_tlab_(false), thread_(nullptr) { 2372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(begin, end); 2382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(static_cast<size_t>(end - begin), kRegionSize); 2392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Clear() { 2422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi top_ = begin_; 2432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionFree; 2442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi objects_allocated_ = 0; 2452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = 0; 2462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ = static_cast<size_t>(-1); 2472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (!kMadviseZeroes) { 2482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi memset(begin_, 0, end_ - begin_); 2492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi madvise(begin_, end_ - begin_, MADV_DONTNEED); 2512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_ = false; 2522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_a_tlab_ = false; 2532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi thread_ = nullptr; 2542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ALWAYS_INLINE mirror::Object* Alloc(size_t num_bytes, size_t* bytes_allocated, 2572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t* usable_size); 2582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsFree() const { 2602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool is_free = state_ == kRegionFree; 2612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (is_free) { 2622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(begin_, top_); 2632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(objects_allocated_, 0U); 2642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return is_free; 2662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Given a free region, declare it non-free (allocated). 2692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Unfree(uint32_t alloc_time) { 2702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsFree()); 2712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionToSpace; 2722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = alloc_time; 2732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void UnfreeLarge(uint32_t alloc_time) { 2762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsFree()); 2772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionLargeToSpace; 2782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = alloc_time; 2792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void UnfreeLargeTail(uint32_t alloc_time) { 2822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsFree()); 2832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionLargeTailToSpace; 2842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = alloc_time; 2852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetNewlyAllocated() { 2882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_ = true; 2892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Non-large, non-large-tail. 2922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsNormal() const { 2932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return state_ == kRegionToSpace || state_ == kRegionFromSpace || 2942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ == kRegionUnevacFromSpace; 2952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsLarge() const { 2982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool is_large = state_ == kRegionLargeToSpace || state_ == kRegionLargeFromSpace || 2992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ == kRegionLargeUnevacFromSpace; 3002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (is_large) { 3012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(begin_ + 1 * MB, top_); 3022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return is_large; 3042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsLargeTail() const { 3072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool is_large_tail = state_ == kRegionLargeTailToSpace || 3082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ == kRegionLargeTailFromSpace || 3092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ == kRegionLargeTailUnevacFromSpace; 3102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (is_large_tail) { 3112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(begin_, top_); 3122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return is_large_tail; 3142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t Idx() const { 3172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return idx_; 3182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInFromSpace() const { 3212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return state_ == kRegionFromSpace || state_ == kRegionLargeFromSpace || 3222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ == kRegionLargeTailFromSpace; 3232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInToSpace() const { 3262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return state_ == kRegionToSpace || state_ == kRegionLargeToSpace || 3272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ == kRegionLargeTailToSpace; 3282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInUnevacFromSpace() const { 3312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return state_ == kRegionUnevacFromSpace || state_ == kRegionLargeUnevacFromSpace || 3322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ == kRegionLargeTailUnevacFromSpace; 3332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetAsFromSpace() { 3362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi switch (state_) { 3372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case kRegionToSpace: 3382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionFromSpace; 3392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi break; 3402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case kRegionLargeToSpace: 3412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionLargeFromSpace; 3422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi break; 3432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case kRegionLargeTailToSpace: 3442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionLargeTailFromSpace; 3452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi break; 3462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi default: 3472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi LOG(FATAL) << "Unexpected region state : " << static_cast<uint>(state_) 3482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi << " idx=" << idx_; 3492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ = static_cast<size_t>(-1); 3512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetAsUnevacFromSpace() { 3542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi switch (state_) { 3552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case kRegionToSpace: 3562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionUnevacFromSpace; 3572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi break; 3582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case kRegionLargeToSpace: 3592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionLargeUnevacFromSpace; 3602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi break; 3612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case kRegionLargeTailToSpace: 3622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionLargeTailUnevacFromSpace; 3632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi break; 3642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi default: 3652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi LOG(FATAL) << "Unexpected region state : " << static_cast<uint>(state_) 3662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi << " idx=" << idx_; 3672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ = 0U; 3692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetUnevacFromSpaceAsToSpace() { 3722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi switch (state_) { 3732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case kRegionUnevacFromSpace: 3742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionToSpace; 3752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi break; 3762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case kRegionLargeUnevacFromSpace: 3772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionLargeToSpace; 3782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi break; 3792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi case kRegionLargeTailUnevacFromSpace: 3802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi state_ = kRegionLargeTailToSpace; 3812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi break; 3822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi default: 3832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi LOG(FATAL) << "Unexpected region state : " << static_cast<uint>(state_) 3842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi << " idx=" << idx_; 3852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ALWAYS_INLINE bool ShouldBeEvacuated(); 3892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AddLiveBytes(size_t live_bytes) { 3912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsInUnevacFromSpace()); 3922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(!IsLargeTail()); 3932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_NE(live_bytes_, static_cast<size_t>(-1)); 3942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ += live_bytes; 3952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(live_bytes_, BytesAllocated()); 3962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t LiveBytes() const { 3992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return live_bytes_; 4002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint GetLivePercent() const { 4032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsInToSpace()); 4042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(!IsLargeTail()); 4052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_NE(live_bytes_, static_cast<size_t>(-1)); 4062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(live_bytes_, BytesAllocated()); 4072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t bytes_allocated = RoundUp(BytesAllocated(), kRegionSize); 4082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_GE(bytes_allocated, 0U); 4092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint result = (live_bytes_ * 100U) / bytes_allocated; 4102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(result, 100U); 4112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return result; 4122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t BytesAllocated() const { 4152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (IsLarge()) { 4162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(begin_ + kRegionSize, top_); 4172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return static_cast<size_t>(top_ - begin_); 4182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else if (IsLargeTail()) { 4192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(begin_, top_); 4202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 4212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else { 4222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsNormal()) << static_cast<uint>(state_); 4232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(begin_, top_); 4242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t bytes = static_cast<size_t>(top_ - begin_); 4252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(bytes, kRegionSize); 4262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return bytes; 4272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t ObjectsAllocated() const { 4312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (IsLarge()) { 4322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(begin_ + 1 * MB, top_); 4332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(objects_allocated_, 0U); 4342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 1; 4352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else if (IsLargeTail()) { 4362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(begin_, top_); 4372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(objects_allocated_, 0U); 4382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 4392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else { 4402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsNormal()) << static_cast<uint>(state_); 4412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return objects_allocated_; 4422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* Begin() const { 4462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return begin_; 4472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* Top() const { 4502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return top_; 4512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetTop(uint8_t* new_top) { 4542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi top_ = new_top; 4552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* End() const { 4582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return end_; 4592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool Contains(mirror::Object* ref) const { 4622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return begin_ <= reinterpret_cast<uint8_t*>(ref) && reinterpret_cast<uint8_t*>(ref) < end_; 4632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Dump(std::ostream& os) const; 4662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void RecordThreadLocalAllocations(size_t num_objects, size_t num_bytes) { 4682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsNormal()); 4692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(objects_allocated_, 0U); 4702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(top_, end_); 4712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi objects_allocated_ = num_objects; 4722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi top_ = begin_ + num_bytes; 4732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(top_, end_); 4742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi private: 4772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t idx_; // The region's index in the region space. 4782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* begin_; // The begin address of the region. 4792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Can't use Atomic<uint8_t*> as Atomic's copy operator is implicitly deleted. 4802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* top_; // The current position of the allocation. 4812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* end_; // The end address of the region. 4822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t state_; // The region state (see RegionState). 4832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t objects_allocated_; // The number of objects allocated. 4842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint32_t alloc_time_; // The allocation time of the region. 4852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t live_bytes_; // The live bytes. Used to compute the live percent. 4862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool is_newly_allocated_; // True if it's allocated after the last collection. 4872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool is_a_tlab_; // True if it's a tlab. 4882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Thread* thread_; // The owning thread if it's a tlab. 4892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi friend class RegionSpace; 4912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi }; 4922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* RefToRegion(mirror::Object* ref) LOCKS_EXCLUDED(region_lock_) { 4942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi MutexLock mu(Thread::Current(), region_lock_); 4952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return RefToRegionLocked(ref); 4962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* RefToRegionUnlocked(mirror::Object* ref) NO_THREAD_SAFETY_ANALYSIS { 4992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // For a performance reason (this is frequently called via 5002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // IsInFromSpace() etc.) we avoid taking a lock here. Note that 5012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // since we only change a region from to-space to from-space only 5022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // during a pause (SetFromSpace()) and from from-space to free 5032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // (after GC is done) as long as ref is a valid reference into an 5042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // allocated region, it's safe to access the region state without 5052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // the lock. 5062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return RefToRegionLocked(ref); 5072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 5082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* RefToRegionLocked(mirror::Object* ref) EXCLUSIVE_LOCKS_REQUIRED(region_lock_) { 5102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(HasAddress(ref)); 5112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uintptr_t offset = reinterpret_cast<uintptr_t>(ref) - reinterpret_cast<uintptr_t>(Begin()); 5122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t reg_idx = offset / kRegionSize; 5132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(reg_idx, num_regions_); 5142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* reg = ®ions_[reg_idx]; 5152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(reg->Idx(), reg_idx); 5162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(reg->Contains(ref)); 5172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return reg; 5182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 5192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* GetNextObject(mirror::Object* obj) 5212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 5222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Mutex region_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 5242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint32_t time_; // The time as the number of collections since the startup. 5262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t num_regions_; // The number of regions in this space. 5272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t num_non_free_regions_; // The number of non-free regions in this space. 5282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi std::unique_ptr<Region[]> regions_ GUARDED_BY(region_lock_); 5292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // The pointer to the region array. 5302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* current_region_; // The region that's being allocated currently. 5312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* evac_region_; // The region that's being evacuated to currently. 5322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region full_region_; // The dummy/sentinel region that looks full. 5332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DISALLOW_COPY_AND_ASSIGN(RegionSpace); 5352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi}; 5362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} // namespace space 5382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} // namespace gc 5392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} // namespace art 5402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#endif // ART_RUNTIME_GC_SPACE_REGION_SPACE_H_ 542