space.h revision 31f441464c0c8f840aba37e236ad133f30308d70
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;
467410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartierclass BumpPointerSpace;
47a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartierclass ContinuousMemMapAllocSpace;
48590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierclass ContinuousSpace;
49590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierclass DiscontinuousSpace;
50cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass MallocSpace;
51cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass DlMallocSpace;
52cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass RosAllocSpace;
531d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass ImageSpace;
541d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass LargeObjectSpace;
55a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartierclass ZygoteSpace;
561d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
570f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartierstatic constexpr bool kDebugSpaces = kIsDebugBuild;
581d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
591d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// See Space::GetGcRetentionPolicy.
601d54e73444e017d3a65234e0f193846f3e27472bIan Rogersenum GcRetentionPolicy {
611d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Objects are retained forever with this policy for a space.
621d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kGcRetentionPolicyNeverCollect,
631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Every GC cycle will attempt to collect objects in this space.
641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kGcRetentionPolicyAlwaysCollect,
651d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Objects will be considered for collection only in "full" GC cycles, ie faster partial
661d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // collections won't scan these areas such as the Zygote.
671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kGcRetentionPolicyFullCollect,
681d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
691d54e73444e017d3a65234e0f193846f3e27472bIan Rogersstd::ostream& operator<<(std::ostream& os, const GcRetentionPolicy& policy);
701d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
711d54e73444e017d3a65234e0f193846f3e27472bIan Rogersenum SpaceType {
721d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kSpaceTypeImageSpace,
73a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  kSpaceTypeMallocSpace,
741d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kSpaceTypeZygoteSpace,
75590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  kSpaceTypeBumpPointerSpace,
761d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  kSpaceTypeLargeObjectSpace,
771d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
781d54e73444e017d3a65234e0f193846f3e27472bIan Rogersstd::ostream& operator<<(std::ostream& os, const SpaceType& space_type);
791d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
801d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// A space contains memory allocated for managed objects.
811d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass Space {
821d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
831d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Dump space. Also key method for C++ vtables.
841d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual void Dump(std::ostream& os) const;
851d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
861d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Name of the space. May vary, for example before/after the Zygote fork.
871d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  const char* GetName() const {
881d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return name_.c_str();
891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
901d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
911d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // The policy of when objects are collected associated with this space.
921d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  GcRetentionPolicy GetGcRetentionPolicy() const {
931d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return gc_retention_policy_;
941d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
951d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
961d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Is the given object contained within this space?
971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual bool Contains(const mirror::Object* obj) const = 0;
981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // The kind of space this: image, alloc, zygote, large object.
1001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual SpaceType GetType() const = 0;
1011d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Is this an image space, ie one backed by a memory mapped image file.
1031d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool IsImageSpace() const {
1041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return GetType() == kSpaceTypeImageSpace;
1051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  ImageSpace* AsImageSpace();
1071d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1081d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Is this a dlmalloc backed allocation space?
109cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  bool IsMallocSpace() const {
1101d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    SpaceType type = GetType();
111a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    return type == kSpaceTypeMallocSpace;
1121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
113cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  MallocSpace* AsMallocSpace();
114cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
115cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual bool IsDlMallocSpace() const {
116cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return false;
117cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
1186fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual DlMallocSpace* AsDlMallocSpace();
1196fac447555dc94a935b78198479cce645c837b89Ian Rogers
120cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual bool IsRosAllocSpace() const {
121cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return false;
122cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
1236fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual RosAllocSpace* AsRosAllocSpace();
1241d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1256fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Is this the space allocated into by the Zygote and no-longer in use for allocation?
1261d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool IsZygoteSpace() const {
1271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return GetType() == kSpaceTypeZygoteSpace;
1281d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1296fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual ZygoteSpace* AsZygoteSpace();
1301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
131590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Is this space a bump pointer space?
132590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  bool IsBumpPointerSpace() const {
133590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return GetType() == kSpaceTypeBumpPointerSpace;
134590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
1356fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual BumpPointerSpace* AsBumpPointerSpace();
136590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
1371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Does this space hold large objects and implement the large object space abstraction?
1381d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool IsLargeObjectSpace() const {
1391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return GetType() == kSpaceTypeLargeObjectSpace;
1401d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  LargeObjectSpace* AsLargeObjectSpace();
1421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
143590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsContinuousSpace() const {
144590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return false;
145590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
146590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  ContinuousSpace* AsContinuousSpace();
147590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
148590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsDiscontinuousSpace() const {
149590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return false;
150590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
151590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  DiscontinuousSpace* AsDiscontinuousSpace();
152590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
153590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsAllocSpace() const {
154590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return false;
155590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
1566fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual AllocSpace* AsAllocSpace();
157590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
158a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  virtual bool IsContinuousMemMapAllocSpace() const {
159a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    return false;
160a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  }
1616fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual ContinuousMemMapAllocSpace* AsContinuousMemMapAllocSpace();
162a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier
16331f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier  // Returns true if objects in the space are movable.
16431f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier  virtual bool CanMoveObjects() const = 0;
16531f441464c0c8f840aba37e236ad133f30308d70Mathieu 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:
179a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  struct SweepCallbackContext {
180a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    bool swap_bitmaps;
181a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    Heap* heap;
182a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    space::Space* space;
183a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    Thread* self;
184a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    size_t freed_objects;
185a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    size_t freed_bytes;
186a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  };
187a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier
1881d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // When should objects within this space be reclaimed? Not constant as we vary it in the case
1891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // of Zygote forking.
1901d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  GcRetentionPolicy gc_retention_policy_;
1911d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
192590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier private:
1931d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  friend class art::gc::Heap;
1941d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(Space);
1951d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
1961d54e73444e017d3a65234e0f193846f3e27472bIan Rogersstd::ostream& operator<<(std::ostream& os, const Space& space);
1971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// AllocSpace interface.
1991d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass AllocSpace {
2001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
2011d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Number of bytes currently allocated.
202be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi  virtual uint64_t GetBytesAllocated() = 0;
2031d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Number of objects currently allocated.
204be031fff278799984166ec866c2dd202447e0f23Hiroshi Yamauchi  virtual uint64_t GetObjectsAllocated() = 0;
2051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
20650b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi  // Allocate num_bytes without allowing growth. If the allocation
20750b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi  // succeeds, the output parameter bytes_allocated will be set to the
20850b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi  // actually allocated bytes which is >= num_bytes.
2096fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated,
2106fac447555dc94a935b78198479cce645c837b89Ian Rogers                                size_t* usable_size) = 0;
2111d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Return the storage space required by obj.
2136fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual size_t AllocationSize(mirror::Object* obj, size_t* usable_size) = 0;
2141d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2151d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Returns how many bytes were freed.
2161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual size_t Free(Thread* self, mirror::Object* ptr) = 0;
2171d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2181d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Returns how many bytes were freed.
2191d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) = 0;
2201d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2216fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Revoke any sort of thread-local buffers that are used to speed up allocations for the given
2226fac447555dc94a935b78198479cce645c837b89Ian Rogers  // thread, if the alloc space implementation uses any.
2236fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual void RevokeThreadLocalBuffers(Thread* thread) = 0;
224cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
2256fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Revoke any sort of thread-local buffers that are used to speed up allocations for all the
2266fac447555dc94a935b78198479cce645c837b89Ian Rogers  // threads, if the alloc space implementation uses any.
2276fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual void RevokeAllThreadLocalBuffers() = 0;
228cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
2291d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected:
2301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  AllocSpace() {}
2311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual ~AllocSpace() {}
2321d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private:
2341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(AllocSpace);
2351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
2361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// Continuous spaces have bitmaps, and an address range. Although not required, objects within
2381d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// continuous spaces can be marked in the card table.
2391d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass ContinuousSpace : public Space {
2401d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
241590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Address at which the space begins.
2421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  byte* Begin() const {
2431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return begin_;
2441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
246590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Current address at which the space ends, which may vary as the space is filled.
2471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  byte* End() const {
2481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return end_;
2491d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2501d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
251590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // The end of the address range covered by the space.
252590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  byte* Limit() const {
253590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return limit_;
254590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
255590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
256590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Change the end of the space. Be careful with use since changing the end of a space to an
257590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // invalid value may break the GC.
258590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  void SetEnd(byte* end) {
259590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    end_ = end;
260590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
261590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
262590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  void SetLimit(byte* limit) {
263590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    limit_ = limit;
264590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
265590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
2661d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Current size of space
2671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  size_t Size() const {
2681d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return End() - Begin();
2691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2701d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2711d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual accounting::SpaceBitmap* GetLiveBitmap() const = 0;
2721d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual accounting::SpaceBitmap* GetMarkBitmap() const = 0;
2731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
274590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Maximum which the mapped space can grow to.
275590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual size_t Capacity() const {
276590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return Limit() - Begin();
277590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
278590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
2791d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Is object within this space? We check to see if the pointer is beyond the end first as
2801d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // continuous spaces are iterated over from low to high.
2811d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool HasAddress(const mirror::Object* obj) const {
2821d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    const byte* byte_ptr = reinterpret_cast<const byte*>(obj);
283590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return byte_ptr >= Begin() && byte_ptr < Limit();
2841d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2851d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2861d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  bool Contains(const mirror::Object* obj) const {
2871d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return HasAddress(obj);
2881d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
2891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
290590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsContinuousSpace() const {
291590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return true;
292590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
293590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
2941d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual ~ContinuousSpace() {}
2951d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
2961d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected:
2971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  ContinuousSpace(const std::string& name, GcRetentionPolicy gc_retention_policy,
298590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                  byte* begin, byte* end, byte* limit) :
299590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      Space(name, gc_retention_policy), begin_(begin), end_(end), limit_(limit) {
3001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3011d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // The beginning of the storage for fast access.
303590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  byte* begin_;
3041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Current end of the space.
306590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  byte* volatile end_;
307590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
308590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  // Limit of the space.
309590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  byte* limit_;
3101d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3111d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private:
3121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(ContinuousSpace);
3131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
3141d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3151d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// A space where objects may be allocated higgledy-piggledy throughout virtual memory. Currently
3161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// the card table can't cover these objects and so the write barrier shouldn't be triggered. This
3171d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// is suitable for use for large primitive arrays.
3181d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass DiscontinuousSpace : public Space {
3191d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
320db7f37d57b6ac83abe6815d0cd5c50701b6be821Mathieu Chartier  accounting::ObjectSet* GetLiveObjects() const {
3211d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return live_objects_.get();
3221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3231d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
324db7f37d57b6ac83abe6815d0cd5c50701b6be821Mathieu Chartier  accounting::ObjectSet* GetMarkObjects() const {
3251d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return mark_objects_.get();
3261d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
328590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  virtual bool IsDiscontinuousSpace() const {
329590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return true;
330590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
331590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
3321d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual ~DiscontinuousSpace() {}
3331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected:
3351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DiscontinuousSpace(const std::string& name, GcRetentionPolicy gc_retention_policy);
3361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
337db7f37d57b6ac83abe6815d0cd5c50701b6be821Mathieu Chartier  UniquePtr<accounting::ObjectSet> live_objects_;
338db7f37d57b6ac83abe6815d0cd5c50701b6be821Mathieu Chartier  UniquePtr<accounting::ObjectSet> mark_objects_;
3391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3401d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private:
3411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(DiscontinuousSpace);
3421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
3431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3441d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass MemMapSpace : public ContinuousSpace {
3451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
3461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Size of the space without a limit on its growth. By default this is just the Capacity, but
3471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // for the allocation space we support starting with a small heap and then extending it.
3481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  virtual size_t NonGrowthLimitCapacity() const {
3491d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return Capacity();
3501d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3511d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3521d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  MemMap* GetMemMap() {
3531d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return mem_map_.get();
3541d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3551d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
3561d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  const MemMap* GetMemMap() const {
3571d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return mem_map_.get();
3581d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
3591d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
360e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  MemMap* ReleaseMemMap() {
361e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier    return mem_map_.release();
362e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  }
363e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier
364590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier protected:
365590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  MemMapSpace(const std::string& name, MemMap* mem_map, byte* begin, byte* end, byte* limit,
366590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier              GcRetentionPolicy gc_retention_policy)
367590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      : ContinuousSpace(name, gc_retention_policy, begin, end, limit),
368590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        mem_map_(mem_map) {
369590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
370590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
3711d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Underlying storage of the space
3721d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  UniquePtr<MemMap> mem_map_;
3731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
374590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier private:
3751d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(MemMapSpace);
3761d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
3771d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
378590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier// Used by the heap compaction interface to enable copying from one type of alloc space to another.
379590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierclass ContinuousMemMapAllocSpace : public MemMapSpace, public AllocSpace {
380590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier public:
3816fac447555dc94a935b78198479cce645c837b89Ian Rogers  bool IsAllocSpace() const OVERRIDE {
382590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return true;
383590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
3846fac447555dc94a935b78198479cce645c837b89Ian Rogers  AllocSpace* AsAllocSpace() OVERRIDE {
385590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return this;
386590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
387590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
3886fac447555dc94a935b78198479cce645c837b89Ian Rogers  bool IsContinuousMemMapAllocSpace() const OVERRIDE {
389a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    return true;
390a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  }
3916fac447555dc94a935b78198479cce645c837b89Ian Rogers  ContinuousMemMapAllocSpace* AsContinuousMemMapAllocSpace() {
392a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    return this;
393a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  }
394a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier
395a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  bool HasBoundBitmaps() const EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
396a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  void BindLiveToMarkBitmap()
397a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier      EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
398a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  void UnBindBitmaps() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
3991f3b5358b28a83f0929bdd8ce738f06908677fb7Mathieu Chartier  // Swap the live and mark bitmaps of this space. This is used by the GC for concurrent sweeping.
4001f3b5358b28a83f0929bdd8ce738f06908677fb7Mathieu Chartier  void SwapBitmaps();
401a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier
40231f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier  // Reset the space back to an empty space and release memory.
4036fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual void Clear() = 0;
404590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
4056fac447555dc94a935b78198479cce645c837b89Ian Rogers  accounting::SpaceBitmap* GetLiveBitmap() const {
406a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    return live_bitmap_.get();
407a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  }
4086fac447555dc94a935b78198479cce645c837b89Ian Rogers
4096fac447555dc94a935b78198479cce645c837b89Ian Rogers  accounting::SpaceBitmap* GetMarkBitmap() const {
410a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier    return mark_bitmap_.get();
411a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  }
412a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier
4136fac447555dc94a935b78198479cce645c837b89Ian Rogers  void Sweep(bool swap_bitmaps, size_t* freed_objects, size_t* freed_bytes);
4146fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual accounting::SpaceBitmap::SweepCallback* GetSweepCallback() = 0;
415a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier
416590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier protected:
417a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  UniquePtr<accounting::SpaceBitmap> live_bitmap_;
418a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  UniquePtr<accounting::SpaceBitmap> mark_bitmap_;
419a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  UniquePtr<accounting::SpaceBitmap> temp_bitmap_;
420a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier
421590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  ContinuousMemMapAllocSpace(const std::string& name, MemMap* mem_map, byte* begin,
422590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                             byte* end, byte* limit, GcRetentionPolicy gc_retention_policy)
423590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      : MemMapSpace(name, mem_map, begin, end, limit, gc_retention_policy) {
424590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
425590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
426590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier private:
427a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  friend class gc::Heap;
428590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  DISALLOW_COPY_AND_ASSIGN(ContinuousMemMapAllocSpace);
429590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier};
430590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
4311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace space
4321d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace gc
4331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace art
4341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
435fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_GC_SPACE_SPACE_H_
436