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 382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Create a region space 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. 412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi static RegionSpace* Create(const std::string& name, size_t capacity, uint8_t* requested_begin); 422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 432cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Allocate num_bytes, returns null if the space is full. 442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated, 454460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, size_t* bytes_tl_bulk_allocated) OVERRIDE; 462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Thread-unsafe allocation for when mutators are suspended, used by the semispace collector. 472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* AllocThreadUnsafe(Thread* self, size_t num_bytes, size_t* bytes_allocated, 484460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, size_t* bytes_tl_bulk_allocated) 492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi OVERRIDE EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_); 502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // The main allocation routine. 512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<bool kForEvac> 522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ALWAYS_INLINE mirror::Object* AllocNonvirtual(size_t num_bytes, size_t* bytes_allocated, 534460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, 544460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated); 552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Allocate/free large objects (objects that are larger than the region size.) 562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<bool kForEvac> 574460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi mirror::Object* AllocLarge(size_t num_bytes, size_t* bytes_allocated, size_t* usable_size, 584460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated); 592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void FreeLarge(mirror::Object* large_obj, size_t bytes_allocated); 602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Return the storage space required by obj. 622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t AllocationSize(mirror::Object* obj, size_t* usable_size) OVERRIDE 632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return AllocationSizeNonvirtual(obj, usable_size); 652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size) 672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t Free(Thread*, mirror::Object*) OVERRIDE { 702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi UNIMPLEMENTED(FATAL); 712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t FreeList(Thread*, size_t, mirror::Object**) OVERRIDE { 742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi UNIMPLEMENTED(FATAL); 752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi accounting::ContinuousSpaceBitmap* GetLiveBitmap() const OVERRIDE { 782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // No live bitmap. 792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return nullptr; 802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi accounting::ContinuousSpaceBitmap* GetMarkBitmap() const OVERRIDE { 822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // No mark bitmap. 832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return nullptr; 842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Clear() OVERRIDE LOCKS_EXCLUDED(region_lock_); 872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Dump(std::ostream& os) const; 892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void DumpRegions(std::ostream& os); 902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void DumpNonFreeRegions(std::ostream& os); 912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 924460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t RevokeThreadLocalBuffers(Thread* thread) LOCKS_EXCLUDED(region_lock_); 932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void RevokeThreadLocalBuffersLocked(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(region_lock_); 944460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t RevokeAllThreadLocalBuffers() LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_, 954460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi Locks::thread_list_lock_); 962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AssertThreadLocalBuffersAreRevoked(Thread* thread) LOCKS_EXCLUDED(region_lock_); 972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AssertAllThreadLocalBuffersAreRevoked() LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_, 982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Locks::thread_list_lock_); 992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 100d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi enum class RegionType : uint8_t { 101d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeAll, // All types. 102d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeFromSpace, // From-space. To be evacuated. 103d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeUnevacFromSpace, // Unevacuated from-space. Not to be evacuated. 104d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeToSpace, // To-space. 105d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionTypeNone, // None. 106d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi }; 107d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 108d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi enum class RegionState : uint8_t { 109d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionStateFree, // Free region. 110d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionStateAllocated, // Allocated region. 111d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionStateLarge, // Large allocated (allocation larger than the region size). 112d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi kRegionStateLargeTail, // Large tail (non-first regions of a large allocation). 1132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi }; 1142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 115d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi template<RegionType kRegionType> uint64_t GetBytesAllocatedInternal(); 116d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi template<RegionType kRegionType> uint64_t GetObjectsAllocatedInternal(); 1172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetBytesAllocated() { 118d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetBytesAllocatedInternal<RegionType::kRegionTypeAll>(); 1192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetObjectsAllocated() { 121d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetObjectsAllocatedInternal<RegionType::kRegionTypeAll>(); 1222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetBytesAllocatedInFromSpace() { 124d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetBytesAllocatedInternal<RegionType::kRegionTypeFromSpace>(); 1252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetObjectsAllocatedInFromSpace() { 127d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetObjectsAllocatedInternal<RegionType::kRegionTypeFromSpace>(); 1282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetBytesAllocatedInUnevacFromSpace() { 130d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetBytesAllocatedInternal<RegionType::kRegionTypeUnevacFromSpace>(); 1312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t GetObjectsAllocatedInUnevacFromSpace() { 133d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return GetObjectsAllocatedInternal<RegionType::kRegionTypeUnevacFromSpace>(); 1342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool CanMoveObjects() const OVERRIDE { 1372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return true; 1382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool Contains(const mirror::Object* obj) const { 1412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi const uint8_t* byte_obj = reinterpret_cast<const uint8_t*>(obj); 1422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return byte_obj >= Begin() && byte_obj < Limit(); 1432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi RegionSpace* AsRegionSpace() OVERRIDE { 1462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return this; 1472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Go through all of the blocks and visit the continuous objects. 1502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Walk(ObjectCallback* callback, void* arg) 1512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 1522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi WalkInternal<false>(callback, arg); 1532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void WalkToSpace(ObjectCallback* callback, void* arg) 1562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 1572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi WalkInternal<true>(callback, arg); 1582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi accounting::ContinuousSpaceBitmap::SweepCallback* GetSweepCallback() OVERRIDE { 1612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return nullptr; 1622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) OVERRIDE 1642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Object alignment within the space. 1672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi static constexpr size_t kAlignment = kObjectAlignment; 1682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // The region size. 1692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi static constexpr size_t kRegionSize = 1 * MB; 1702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInFromSpace(mirror::Object* ref) { 1722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (HasAddress(ref)) { 1732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 1742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return r->IsInFromSpace(); 1752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return false; 1772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInUnevacFromSpace(mirror::Object* ref) { 1802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (HasAddress(ref)) { 1812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 1822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return r->IsInUnevacFromSpace(); 1832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return false; 1852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 1872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInToSpace(mirror::Object* ref) { 1882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (HasAddress(ref)) { 1892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 1902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return r->IsInToSpace(); 1912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return false; 1932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 195d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi RegionType GetRegionType(mirror::Object* ref) { 196d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi if (HasAddress(ref)) { 197d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi Region* r = RefToRegionUnlocked(ref); 198d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return r->Type(); 199d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 200d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return RegionType::kRegionTypeNone; 201d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 202d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 2032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetFromSpace(accounting::ReadBarrierTable* rb_table, bool force_evacuate_all) 2042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi LOCKS_EXCLUDED(region_lock_); 2052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t FromSpaceSize(); 2072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t UnevacFromSpaceSize(); 2082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t ToSpaceSize(); 2092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void ClearFromSpace(); 2102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AddLiveBytes(mirror::Object* ref, size_t alloc_size) { 212d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi Region* reg = RefToRegionUnlocked(ref); 2132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi reg->AddLiveBytes(alloc_size); 2142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AssertAllRegionLiveBytesZeroOrCleared(); 2172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void RecordAlloc(mirror::Object* ref); 2192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool AllocNewTlab(Thread* self); 2202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint32_t Time() { 2222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return time_; 2232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi private: 2262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi RegionSpace(const std::string& name, MemMap* mem_map); 2272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi template<bool kToSpaceOnly> 2292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void WalkInternal(ObjectCallback* callback, void* arg) NO_THREAD_SAFETY_ANALYSIS; 2302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi class Region { 2322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi public: 2332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region() 2342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi : idx_(static_cast<size_t>(-1)), 235d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi begin_(nullptr), top_(nullptr), end_(nullptr), 236d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_(RegionState::kRegionStateAllocated), type_(RegionType::kRegionTypeToSpace), 2372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi objects_allocated_(0), alloc_time_(0), live_bytes_(static_cast<size_t>(-1)), 2382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_(false), is_a_tlab_(false), thread_(nullptr) {} 2392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region(size_t idx, uint8_t* begin, uint8_t* end) 241d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi : idx_(idx), begin_(begin), top_(begin), end_(end), 242d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_(RegionState::kRegionStateFree), type_(RegionType::kRegionTypeNone), 2432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi objects_allocated_(0), alloc_time_(0), live_bytes_(static_cast<size_t>(-1)), 2442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_(false), is_a_tlab_(false), thread_(nullptr) { 2452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(begin, end); 2462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(static_cast<size_t>(end - begin), kRegionSize); 2472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 249d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi RegionState State() const { 250d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return state_; 251d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 252d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 253d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi RegionType Type() const { 254d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_; 255d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 256d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 2572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Clear() { 2582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi top_ = begin_; 259d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_ = RegionState::kRegionStateFree; 260d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeNone; 2612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi objects_allocated_ = 0; 2622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = 0; 2632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ = static_cast<size_t>(-1); 2642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (!kMadviseZeroes) { 2652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi memset(begin_, 0, end_ - begin_); 2662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi madvise(begin_, end_ - begin_, MADV_DONTNEED); 2682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_ = false; 2692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_a_tlab_ = false; 2702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi thread_ = nullptr; 2712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ALWAYS_INLINE mirror::Object* Alloc(size_t num_bytes, size_t* bytes_allocated, 2744460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* usable_size, 2754460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi size_t* bytes_tl_bulk_allocated); 2762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsFree() const { 278d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool is_free = state_ == RegionState::kRegionStateFree; 2792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (is_free) { 280d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(IsInNoSpace()); 2812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(begin_, top_); 2822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(objects_allocated_, 0U); 2832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return is_free; 2852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Given a free region, declare it non-free (allocated). 2882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Unfree(uint32_t alloc_time) { 2892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsFree()); 290d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_ = RegionState::kRegionStateAllocated; 291d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeToSpace; 2922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = alloc_time; 2932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 2942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 2952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void UnfreeLarge(uint32_t alloc_time) { 2962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsFree()); 297d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_ = RegionState::kRegionStateLarge; 298d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeToSpace; 2992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = alloc_time; 3002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void UnfreeLargeTail(uint32_t alloc_time) { 3032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsFree()); 304d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi state_ = RegionState::kRegionStateLargeTail; 305d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeToSpace; 3062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi alloc_time_ = alloc_time; 3072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetNewlyAllocated() { 3102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi is_newly_allocated_ = true; 3112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 313d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi // Non-large, non-large-tail allocated. 314d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool IsAllocated() const { 315d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return state_ == RegionState::kRegionStateAllocated; 3162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 318d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi // Large allocated. 3192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsLarge() const { 320d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool is_large = state_ == RegionState::kRegionStateLarge; 3212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (is_large) { 3222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(begin_ + 1 * MB, top_); 3232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return is_large; 3252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 327d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi // Large-tail allocated. 3282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsLargeTail() const { 329d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool is_large_tail = state_ == RegionState::kRegionStateLargeTail; 3302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (is_large_tail) { 3312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(begin_, top_); 3322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return is_large_tail; 3342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t Idx() const { 3372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return idx_; 3382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInFromSpace() const { 341d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_ == RegionType::kRegionTypeFromSpace; 3422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInToSpace() const { 345d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_ == RegionType::kRegionTypeToSpace; 3462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool IsInUnevacFromSpace() const { 349d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_ == RegionType::kRegionTypeUnevacFromSpace; 350d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi } 351d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 352d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi bool IsInNoSpace() const { 353d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi return type_ == RegionType::kRegionTypeNone; 3542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetAsFromSpace() { 357d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(!IsFree() && IsInToSpace()); 358d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeFromSpace; 3592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ = static_cast<size_t>(-1); 3602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetAsUnevacFromSpace() { 363d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(!IsFree() && IsInToSpace()); 364d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeUnevacFromSpace; 3652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ = 0U; 3662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetUnevacFromSpaceAsToSpace() { 369d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(!IsFree() && IsInUnevacFromSpace()); 370d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi type_ = RegionType::kRegionTypeToSpace; 3712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ALWAYS_INLINE bool ShouldBeEvacuated(); 3742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void AddLiveBytes(size_t live_bytes) { 3762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsInUnevacFromSpace()); 3772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(!IsLargeTail()); 3782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_NE(live_bytes_, static_cast<size_t>(-1)); 3792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi live_bytes_ += live_bytes; 3802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(live_bytes_, BytesAllocated()); 3812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t LiveBytes() const { 3842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return live_bytes_; 3852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint GetLivePercent() const { 3882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(IsInToSpace()); 3892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(!IsLargeTail()); 3902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_NE(live_bytes_, static_cast<size_t>(-1)); 3912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(live_bytes_, BytesAllocated()); 3922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t bytes_allocated = RoundUp(BytesAllocated(), kRegionSize); 3932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_GE(bytes_allocated, 0U); 3942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint result = (live_bytes_ * 100U) / bytes_allocated; 3952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(result, 100U); 3962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return result; 3972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 3982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 3992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t BytesAllocated() const { 4002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (IsLarge()) { 4012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(begin_ + kRegionSize, top_); 4022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return static_cast<size_t>(top_ - begin_); 4032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else if (IsLargeTail()) { 4042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(begin_, top_); 4052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 4062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else { 407d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(IsAllocated()) << static_cast<uint>(state_); 4082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(begin_, top_); 4092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t bytes = static_cast<size_t>(top_ - begin_); 4102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LE(bytes, kRegionSize); 4112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return bytes; 4122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t ObjectsAllocated() const { 4162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (IsLarge()) { 4172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(begin_ + 1 * MB, top_); 4182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(objects_allocated_, 0U); 4192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 1; 4202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else if (IsLargeTail()) { 4212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(begin_, top_); 4222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(objects_allocated_, 0U); 4232cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return 0; 4242cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } else { 425d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(IsAllocated()) << static_cast<uint>(state_); 4262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return objects_allocated_; 4272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* Begin() const { 4312cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return begin_; 4322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* Top() const { 4352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return top_; 4362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void SetTop(uint8_t* new_top) { 4392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi top_ = new_top; 4402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* End() const { 4432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return end_; 4442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool Contains(mirror::Object* ref) const { 4472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return begin_ <= reinterpret_cast<uint8_t*>(ref) && reinterpret_cast<uint8_t*>(ref) < end_; 4482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void Dump(std::ostream& os) const; 4512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi void RecordThreadLocalAllocations(size_t num_objects, size_t num_bytes) { 453d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi DCHECK(IsAllocated()); 4542cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(objects_allocated_, 0U); 4552cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(top_, end_); 4562cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi objects_allocated_ = num_objects; 4572cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi top_ = begin_ + num_bytes; 4582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(top_, end_); 4592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4602cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4612cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi private: 4622cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t idx_; // The region's index in the region space. 4632cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* begin_; // The begin address of the region. 4642cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Can't use Atomic<uint8_t*> as Atomic's copy operator is implicitly deleted. 4652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* top_; // The current position of the allocation. 4662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint8_t* end_; // The end address of the region. 467d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi RegionState state_; // The region state (see RegionState). 468d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi RegionType type_; // The region type (see RegionType). 4692cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint64_t objects_allocated_; // The number of objects allocated. 4702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint32_t alloc_time_; // The allocation time of the region. 4712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t live_bytes_; // The live bytes. Used to compute the live percent. 4722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool is_newly_allocated_; // True if it's allocated after the last collection. 4732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool is_a_tlab_; // True if it's a tlab. 4742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Thread* thread_; // The owning thread if it's a tlab. 4752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi friend class RegionSpace; 4772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi }; 4782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* RefToRegion(mirror::Object* ref) LOCKS_EXCLUDED(region_lock_) { 4802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi MutexLock mu(Thread::Current(), region_lock_); 4812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return RefToRegionLocked(ref); 4822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4842cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* RefToRegionUnlocked(mirror::Object* ref) NO_THREAD_SAFETY_ANALYSIS { 4852cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // For a performance reason (this is frequently called via 4862cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // IsInFromSpace() etc.) we avoid taking a lock here. Note that 4872cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // since we only change a region from to-space to from-space only 4882cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // during a pause (SetFromSpace()) and from from-space to free 4892cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // (after GC is done) as long as ref is a valid reference into an 4902cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // allocated region, it's safe to access the region state without 4912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // the lock. 4922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return RefToRegionLocked(ref); 4932cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 4942cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 4952cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* RefToRegionLocked(mirror::Object* ref) EXCLUSIVE_LOCKS_REQUIRED(region_lock_) { 4962cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(HasAddress(ref)); 4972cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uintptr_t offset = reinterpret_cast<uintptr_t>(ref) - reinterpret_cast<uintptr_t>(Begin()); 4982cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t reg_idx = offset / kRegionSize; 4992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_LT(reg_idx, num_regions_); 5002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* reg = ®ions_[reg_idx]; 5012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK_EQ(reg->Idx(), reg_idx); 5022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DCHECK(reg->Contains(ref)); 5032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return reg; 5042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 5052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi mirror::Object* GetNextObject(mirror::Object* obj) 5072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 5082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Mutex region_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 5102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi uint32_t time_; // The time as the number of collections since the startup. 5122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t num_regions_; // The number of regions in this space. 5132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi size_t num_non_free_regions_; // The number of non-free regions in this space. 5142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi std::unique_ptr<Region[]> regions_ GUARDED_BY(region_lock_); 5152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // The pointer to the region array. 5162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* current_region_; // The region that's being allocated currently. 5172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region* evac_region_; // The region that's being evacuated to currently. 5182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Region full_region_; // The dummy/sentinel region that looks full. 5192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi DISALLOW_COPY_AND_ASSIGN(RegionSpace); 5212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi}; 5222cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 523d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchistd::ostream& operator<<(std::ostream& os, const RegionSpace::RegionState& value); 524d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchistd::ostream& operator<<(std::ostream& os, const RegionSpace::RegionType& value); 525d25f84250700c35f006d5a1d295231af174c3734Hiroshi Yamauchi 5262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} // namespace space 5272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} // namespace gc 5282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} // namespace art 5292cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 5302cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi#endif // ART_RUNTIME_GC_SPACE_REGION_SPACE_H_ 531