space.h revision cf58d4adf461eb9b8e84baa8019054c88cd8acc6
11d54e73444e017d3a65234e0f193846f3e27472bIan Rogers/*
21d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * Copyright (C) 2011 The Android Open Source Project
31d54e73444e017d3a65234e0f193846f3e27472bIan Rogers *
41d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * Licensed under the Apache License, Version 2.0 (the "License");
51d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * you may not use this file except in compliance with the License.
61d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * You may obtain a copy of the License at
71d54e73444e017d3a65234e0f193846f3e27472bIan Rogers *
81d54e73444e017d3a65234e0f193846f3e27472bIan Rogers *      http://www.apache.org/licenses/LICENSE-2.0
91d54e73444e017d3a65234e0f193846f3e27472bIan Rogers *
101d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * Unless required by applicable law or agreed to in writing, software
111d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * distributed under the License is distributed on an "AS IS" BASIS,
121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * See the License for the specific language governing permissions and
141d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * limitations under the License.
151d54e73444e017d3a65234e0f193846f3e27472bIan Rogers */
161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_GC_SPACE_SPACE_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_GC_SPACE_SPACE_H_
191d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
201d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include <string>
211d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "UniquePtr.h"
231d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "base/macros.h"
241d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "base/mutex.h"
251d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/accounting/space_bitmap.h"
261d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "globals.h"
271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "image.h"
281d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "mem_map.h"
291d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
301d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace art {
311d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace mirror {
321d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  class Object;
331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace mirror
341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
351d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace gc {
361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
371d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace accounting {
381d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  class SpaceBitmap;
397934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}  // namespace accounting
401d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
411d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass Heap;
421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
431d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace space {
441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
45590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierclass AllocSpace;
46590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierclass ContinuousSpace;
47590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierclass DiscontinuousSpace;
48cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass MallocSpace;
49cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass DlMallocSpace;
50cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass RosAllocSpace;
511d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass ImageSpace;
521d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass LargeObjectSpace;
531d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
540f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartierstatic constexpr bool kDebugSpaces = kIsDebugBuild;
551d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
561d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// See Space::GetGcRetentionPolicy.
571d54e73444e017d3a65234e0f193846f3e27472bIan Rogersenum GcRetentionPolicy {
581d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Objects are retained forever with this policy for a space.
591d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kGcRetentionPolicyNeverCollect,
601d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Every GC cycle will attempt to collect objects in this space.
611d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kGcRetentionPolicyAlwaysCollect,
621d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Objects will be considered for collection only in "full" GC cycles, ie faster partial
631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // collections won't scan these areas such as the Zygote.
641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kGcRetentionPolicyFullCollect,
651d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
661d54e73444e017d3a65234e0f193846f3e27472bIan Rogersstd::ostream& operator<<(std::ostream& os, const GcRetentionPolicy& policy);
671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
681d54e73444e017d3a65234e0f193846f3e27472bIan Rogersenum SpaceType {
691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kSpaceTypeImageSpace,
701d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kSpaceTypeAllocSpace,
711d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kSpaceTypeZygoteSpace,
72590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  kSpaceTypeBumpPointerSpace,
731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kSpaceTypeLargeObjectSpace,
741d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
751d54e73444e017d3a65234e0f193846f3e27472bIan Rogersstd::ostream& operator<<(std::ostream& os, const SpaceType& space_type);
761d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
771d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// A space contains memory allocated for managed objects.
781d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass Space {
791d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
801d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Dump space. Also key method for C++ vtables.
811d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual void Dump(std::ostream& os) const;
821d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
831d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Name of the space. May vary, for example before/after the Zygote fork.
841d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  const char* GetName() const {
851d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return name_.c_str();
861d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
871d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
881d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // The policy of when objects are collected associated with this space.
891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  GcRetentionPolicy GetGcRetentionPolicy() const {
901d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return gc_retention_policy_;
911d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
921d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
931d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Does the space support allocation?
941d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual bool CanAllocateInto() const {
951d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return true;
961d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Is the given object contained within this space?
991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual bool Contains(const mirror::Object* obj) const = 0;
1001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1011d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // The kind of space this: image, alloc, zygote, large object.
1021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual SpaceType GetType() const = 0;
1031d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Is this an image space, ie one backed by a memory mapped image file.
1051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool IsImageSpace() const {
1061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return GetType() == kSpaceTypeImageSpace;
1071d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1081d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  ImageSpace* AsImageSpace();
1091d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1101d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Is this a dlmalloc backed allocation space?
111cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  bool IsMallocSpace() const {
1121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    SpaceType type = GetType();
1131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return type == kSpaceTypeAllocSpace || type == kSpaceTypeZygoteSpace;
1141d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
115cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  MallocSpace* AsMallocSpace();
116cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
117cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual bool IsDlMallocSpace() const {
118cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return false;
119cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
120cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual DlMallocSpace* AsDlMallocSpace() {
121cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    LOG(FATAL) << "Unreachable";
122cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return NULL;
123cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
124cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual bool IsRosAllocSpace() const {
125cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return false;
126cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
127cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual RosAllocSpace* AsRosAllocSpace() {
128cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    LOG(FATAL) << "Unreachable";
129cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return NULL;
130cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
1311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1321d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Is this the space allocated into by the Zygote and no-longer in use?
1331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool IsZygoteSpace() const {
1341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return GetType() == kSpaceTypeZygoteSpace;
1351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
137590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Is this space a bump pointer space?
138590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  bool IsBumpPointerSpace() const {
139590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return GetType() == kSpaceTypeBumpPointerSpace;
140590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
141590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
1421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Does this space hold large objects and implement the large object space abstraction?
1431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool IsLargeObjectSpace() const {
1441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return GetType() == kSpaceTypeLargeObjectSpace;
1451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  LargeObjectSpace* AsLargeObjectSpace();
1471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
148590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsContinuousSpace() const {
149590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return false;
150590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
151590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  ContinuousSpace* AsContinuousSpace();
152590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
153590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsDiscontinuousSpace() const {
154590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return false;
155590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
156590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  DiscontinuousSpace* AsDiscontinuousSpace();
157590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
158590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsAllocSpace() const {
159590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return false;
160590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
161590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual AllocSpace* AsAllocSpace() {
162590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    LOG(FATAL) << "Unimplemented";
163590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return nullptr;
164590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
165590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
1661d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual ~Space() {}
1671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1681d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected:
1691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  Space(const std::string& name, GcRetentionPolicy gc_retention_policy);
1701d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1711d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  void SetGcRetentionPolicy(GcRetentionPolicy gc_retention_policy) {
1721d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    gc_retention_policy_ = gc_retention_policy;
1731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1741d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1751d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Name of the space that may vary due to the Zygote fork.
1761d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  std::string name_;
1771d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
178590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier protected:
1791d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // When should objects within this space be reclaimed? Not constant as we vary it in the case
1801d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // of Zygote forking.
1811d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  GcRetentionPolicy gc_retention_policy_;
1821d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
183590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier private:
1841d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  friend class art::gc::Heap;
1851d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(Space);
1861d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
1871d54e73444e017d3a65234e0f193846f3e27472bIan Rogersstd::ostream& operator<<(std::ostream& os, const Space& space);
1881d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// AllocSpace interface.
1901d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass AllocSpace {
1911d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
1921d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Number of bytes currently allocated.
193be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi  virtual uint64_t GetBytesAllocated() = 0;
1941d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Number of objects currently allocated.
195be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi  virtual uint64_t GetObjectsAllocated() = 0;
1961d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Number of bytes allocated since the space was created.
197be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi  virtual uint64_t GetTotalBytesAllocated() = 0;
1981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Number of objects allocated since the space was created.
199be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi  virtual uint64_t GetTotalObjectsAllocated() = 0;
2001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
20150b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi  // Allocate num_bytes without allowing growth. If the allocation
20250b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi  // succeeds, the output parameter bytes_allocated will be set to the
20350b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi  // actually allocated bytes which is >= num_bytes.
20450b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi  virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated) = 0;
2051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Return the storage space required by obj.
2071d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual size_t AllocationSize(const mirror::Object* obj) = 0;
2081d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2091d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Returns how many bytes were freed.
2101d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual size_t Free(Thread* self, mirror::Object* ptr) = 0;
2111d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Returns how many bytes were freed.
2131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) = 0;
2141d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
215cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Revoke any sort of thread-local buffers that are used to speed up
216cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // allocations for the given thread, if the alloc space
217cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // implementation uses any. No-op by default.
218cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual void RevokeThreadLocalBuffers(Thread* /*thread*/) {}
219cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
220cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Revoke any sort of thread-local buffers that are used to speed up
221cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // allocations for all the threads, if the alloc space
222cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // implementation uses any. No-op by default.
223cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual void RevokeAllThreadLocalBuffers() {}
224cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
2251d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected:
2261d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  AllocSpace() {}
2271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual ~AllocSpace() {}
2281d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2291d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private:
2301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(AllocSpace);
2311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
2321d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// Continuous spaces have bitmaps, and an address range. Although not required, objects within
2341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// continuous spaces can be marked in the card table.
2351d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass ContinuousSpace : public Space {
2361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
237590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Address at which the space begins.
2381d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  byte* Begin() const {
2391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return begin_;
2401d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
242590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Current address at which the space ends, which may vary as the space is filled.
2431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  byte* End() const {
2441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return end_;
2451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
247590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // The end of the address range covered by the space.
248590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  byte* Limit() const {
249590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return limit_;
250590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
251590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
252590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Change the end of the space. Be careful with use since changing the end of a space to an
253590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // invalid value may break the GC.
254590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  void SetEnd(byte* end) {
255590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    end_ = end;
256590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
257590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
258590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  void SetLimit(byte* limit) {
259590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    limit_ = limit;
260590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
261590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
2621d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Current size of space
2631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  size_t Size() const {
2641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return End() - Begin();
2651d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2661d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual accounting::SpaceBitmap* GetLiveBitmap() const = 0;
2681d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual accounting::SpaceBitmap* GetMarkBitmap() const = 0;
2691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
270590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Maximum which the mapped space can grow to.
271590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual size_t Capacity() const {
272590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return Limit() - Begin();
273590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
274590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
2751d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Is object within this space? We check to see if the pointer is beyond the end first as
2761d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // continuous spaces are iterated over from low to high.
2771d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool HasAddress(const mirror::Object* obj) const {
2781d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    const byte* byte_ptr = reinterpret_cast<const byte*>(obj);
279590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return byte_ptr >= Begin() && byte_ptr < Limit();
2801d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2811d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2821d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool Contains(const mirror::Object* obj) const {
2831d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return HasAddress(obj);
2841d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2851d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
286590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsContinuousSpace() const {
287590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return true;
288590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
289590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
2901d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual ~ContinuousSpace() {}
2911d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2921d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected:
2931d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  ContinuousSpace(const std::string& name, GcRetentionPolicy gc_retention_policy,
294590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                  byte* begin, byte* end, byte* limit) :
295590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      Space(name, gc_retention_policy), begin_(begin), end_(end), limit_(limit) {
2961d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // The beginning of the storage for fast access.
299590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  byte* begin_;
3001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3011d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Current end of the space.
302590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  byte* volatile end_;
303590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
304590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Limit of the space.
305590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  byte* limit_;
3061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3071d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private:
3081d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(ContinuousSpace);
3091d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
3101d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3111d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// A space where objects may be allocated higgledy-piggledy throughout virtual memory. Currently
3121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// the card table can't cover these objects and so the write barrier shouldn't be triggered. This
3131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// is suitable for use for large primitive arrays.
3141d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass DiscontinuousSpace : public Space {
3151d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
3161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  accounting::SpaceSetMap* GetLiveObjects() const {
3171d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return live_objects_.get();
3181d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3191d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3201d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  accounting::SpaceSetMap* GetMarkObjects() const {
3211d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return mark_objects_.get();
3221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3231d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
324590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsDiscontinuousSpace() const {
325590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return true;
326590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
327590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
3281d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual ~DiscontinuousSpace() {}
3291d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected:
3311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DiscontinuousSpace(const std::string& name, GcRetentionPolicy gc_retention_policy);
3321d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  UniquePtr<accounting::SpaceSetMap> live_objects_;
3341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  UniquePtr<accounting::SpaceSetMap> mark_objects_;
3351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private:
3371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(DiscontinuousSpace);
3381d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
3391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3401d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass MemMapSpace : public ContinuousSpace {
3411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
3421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Size of the space without a limit on its growth. By default this is just the Capacity, but
3431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // for the allocation space we support starting with a small heap and then extending it.
3441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual size_t NonGrowthLimitCapacity() const {
3451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return Capacity();
3461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  MemMap* GetMemMap() {
3491d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return mem_map_.get();
3501d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3511d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3521d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  const MemMap* GetMemMap() const {
3531d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return mem_map_.get();
3541d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3551d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
356590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier protected:
357590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  MemMapSpace(const std::string& name, MemMap* mem_map, byte* begin, byte* end, byte* limit,
358590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier              GcRetentionPolicy gc_retention_policy)
359590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      : ContinuousSpace(name, gc_retention_policy, begin, end, limit),
360590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        mem_map_(mem_map) {
361590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
362590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
3631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Underlying storage of the space
3641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  UniquePtr<MemMap> mem_map_;
3651d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
366590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier private:
3671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(MemMapSpace);
3681d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
3691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
370590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier// Used by the heap compaction interface to enable copying from one type of alloc space to another.
371590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierclass ContinuousMemMapAllocSpace : public MemMapSpace, public AllocSpace {
372590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier public:
373590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsAllocSpace() const {
374590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return true;
375590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
376590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
377590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual AllocSpace* AsAllocSpace() {
378590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return this;
379590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
380590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
381590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual void Clear() {
382590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    LOG(FATAL) << "Unimplemented";
383590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
384590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
385590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier protected:
386590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  ContinuousMemMapAllocSpace(const std::string& name, MemMap* mem_map, byte* begin,
387590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                             byte* end, byte* limit, GcRetentionPolicy gc_retention_policy)
388590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      : MemMapSpace(name, mem_map, begin, end, limit, gc_retention_policy) {
389590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
390590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
391590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier private:
392590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  DISALLOW_COPY_AND_ASSIGN(ContinuousMemMapAllocSpace);
393590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier};
394590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
3951d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace space
3961d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace gc
3971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace art
3981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
399fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_GC_SPACE_SPACE_H_
400