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 = &regions_[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