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