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