malloc_space.h revision 7cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5
1cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi/*
2cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * Copyright (C) 2013 The Android Open Source Project
3cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi *
4cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * Licensed under the Apache License, Version 2.0 (the "License");
5cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * you may not use this file except in compliance with the License.
6cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * You may obtain a copy of the License at
7cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi *
8cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi *      http://www.apache.org/licenses/LICENSE-2.0
9cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi *
10cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * Unless required by applicable law or agreed to in writing, software
11cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * distributed under the License is distributed on an "AS IS" BASIS,
12cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * See the License for the specific language governing permissions and
14cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi * limitations under the License.
15cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi */
16cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
17cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#ifndef ART_RUNTIME_GC_SPACE_MALLOC_SPACE_H_
18cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#define ART_RUNTIME_GC_SPACE_MALLOC_SPACE_H_
19cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
20cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "space.h"
21cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
227cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi#include <valgrind.h>
237cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi#include <memcheck/memcheck.h>
247cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
25cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace art {
26cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace gc {
27cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
28cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace collector {
29cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  class MarkSweep;
30cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi}  // namespace collector
31cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
32cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchinamespace space {
33cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
34cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi// TODO: Remove define macro
35cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#define CHECK_MEMORY_CALL(call, args, what) \
36cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  do { \
37cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    int rc = call args; \
38cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    if (UNLIKELY(rc != 0)) { \
39cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi      errno = rc; \
40cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi      PLOG(FATAL) << # call << " failed for " << what; \
41cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    } \
42cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  } while (false)
43cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
44cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi// const bool kUseRosAlloc = true;
45cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
46cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi// A common parent of DlMallocSpace and RosAllocSpace.
47cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass MallocSpace : public ContinuousMemMapAllocSpace {
48cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi public:
49cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  typedef void(*WalkCallback)(void *start, void *end, size_t num_bytes, void* callback_arg);
50cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
51cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  SpaceType GetType() const {
52cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    if (GetGcRetentionPolicy() == kGcRetentionPolicyFullCollect) {
53cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi      return kSpaceTypeZygoteSpace;
54cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    } else {
55cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi      return kSpaceTypeAllocSpace;
56cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    }
57cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
58cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
59cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Allocate num_bytes without allowing the underlying space to grow.
60cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes,
61cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi                                          size_t* bytes_allocated) = 0;
62cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Allocate num_bytes allowing the underlying space to grow.
63cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated) = 0;
64cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Return the storage space required by obj.
65cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual size_t AllocationSize(const mirror::Object* obj) = 0;
66cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual size_t Free(Thread* self, mirror::Object* ptr) = 0;
67cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) = 0;
68cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
69cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#ifndef NDEBUG
70cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual void CheckMoreCoreForPrecondition() {}  // to be overridden in the debug build.
71cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#else
72cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void CheckMoreCoreForPrecondition() {}  // no-op in the non-debug build.
73cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#endif
74cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
75cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void* MoreCore(intptr_t increment);
76cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
77cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Hands unused pages back to the system.
78cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual size_t Trim() = 0;
79cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
80cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be
81cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // in use, indicated by num_bytes equaling zero.
82cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual void Walk(WalkCallback callback, void* arg) = 0;
83cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
84cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Returns the number of bytes that the space has currently obtained from the system. This is
85cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // greater or equal to the amount of live data in the space.
86cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual size_t GetFootprint() = 0;
87cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
88cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore.
89cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual size_t GetFootprintLimit() = 0;
90cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
91cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Set the maximum number of bytes that the heap is allowed to obtain from the system via
92cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When
93cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow.
94cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual void SetFootprintLimit(size_t limit) = 0;
95cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
96cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Removes the fork time growth limit on capacity, allowing the application to allocate up to the
97cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // maximum reserved size of the heap.
98cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void ClearGrowthLimit() {
99cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    growth_limit_ = NonGrowthLimitCapacity();
100cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
101cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
102cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Override capacity so that we only return the possibly limited capacity
103cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  size_t Capacity() const {
104cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return growth_limit_;
105cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
106cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
107cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // The total amount of memory reserved for the alloc space.
108cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  size_t NonGrowthLimitCapacity() const {
109cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return GetMemMap()->Size();
110cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
111cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
112cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  accounting::SpaceBitmap* GetLiveBitmap() const {
113cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return live_bitmap_.get();
114cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
115cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
116cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  accounting::SpaceBitmap* GetMarkBitmap() const {
117cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return mark_bitmap_.get();
118cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
119cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
120cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void Dump(std::ostream& os) const;
121cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
122cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void SetGrowthLimit(size_t growth_limit);
123cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
124cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Swap the live and mark bitmaps of this space. This is used by the GC for concurrent sweeping.
125cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void SwapBitmaps();
126cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
127cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual MallocSpace* CreateInstance(const std::string& name, MemMap* mem_map, void* allocator,
128cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi                                      byte* begin, byte* end, byte* limit, size_t growth_limit) = 0;
129cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
130cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Turn ourself into a zygote space and return a new alloc space which has our unused memory.
131cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  MallocSpace* CreateZygoteSpace(const char* alloc_space_name);
132cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
133cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual uint64_t GetBytesAllocated() = 0;
134cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual uint64_t GetObjectsAllocated() = 0;
135cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual uint64_t GetTotalBytesAllocated() = 0;
136cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual uint64_t GetTotalObjectsAllocated() = 0;
137cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
138cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Returns the old mark bitmap.
139cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  accounting::SpaceBitmap* BindLiveToMarkBitmap();
140cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  bool HasBoundBitmaps() const;
141cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void UnBindBitmaps();
142cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
143cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Returns the class of a recently freed object.
144cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  mirror::Class* FindRecentFreedObject(const mirror::Object* obj);
145cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
146cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Used to ensure that failure happens when you free / allocate into an invalidated space. If we
147cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // don't do this we may get heap corruption instead of a segfault at null.
148cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual void InvalidateAllocator() = 0;
149cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
150cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi protected:
151cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  MallocSpace(const std::string& name, MemMap* mem_map, byte* begin, byte* end,
152cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi              byte* limit, size_t growth_limit);
153cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
154cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  static MemMap* CreateMemMap(const std::string& name, size_t starting_size, size_t* initial_size,
155cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi                              size_t* growth_limit, size_t* capacity, byte* requested_begin);
156cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
157cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  virtual void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size) = 0;
158cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
159cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void RegisterRecentFree(mirror::Object* ptr) EXCLUSIVE_LOCKS_REQUIRED(lock_);
160cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
161cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  UniquePtr<accounting::SpaceBitmap> live_bitmap_;
162cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  UniquePtr<accounting::SpaceBitmap> mark_bitmap_;
163cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  UniquePtr<accounting::SpaceBitmap> temp_bitmap_;
164cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
165cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Recent allocation buffer.
166cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  static constexpr size_t kRecentFreeCount = kDebugSpaces ? (1 << 16) : 0;
167cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  static constexpr size_t kRecentFreeMask = kRecentFreeCount - 1;
168cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  std::pair<const mirror::Object*, mirror::Class*> recent_freed_objects_[kRecentFreeCount];
169cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  size_t recent_free_pos_;
170cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
171cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  static size_t bitmap_index_;
172cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
173cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Used to ensure mutual exclusion when the allocation spaces data structures are being modified.
174cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
175cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
176cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // The capacity of the alloc space until such time that ClearGrowthLimit is called.
177cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // The underlying mem_map_ controls the maximum size we allow the heap to grow to. The growth
178cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // limit is a value <= to the mem_map_ capacity used for ergonomic reasons because of the zygote.
179cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Prior to forking the zygote the heap will have a maximally sized mem_map_ but the growth_limit_
180cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // will be set to a lower value. The growth_limit_ is used as the capacity of the alloc_space_,
181cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // however, capacity normally can't vary. In the case of the growth_limit_ it can be cleared
182cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // one time by a call to ClearGrowthLimit.
183cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  size_t growth_limit_;
184cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
185cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  friend class collector::MarkSweep;
186cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
187e5eedcb4a634246d1f912992853441f715d705ccHiroshi Yamauchi private:
188cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  DISALLOW_COPY_AND_ASSIGN(MallocSpace);
189cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi};
190cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
1917cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi// Number of bytes to use as a red zone (rdz). A red zone of this size will be placed before and
1927cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi// after each allocation. 8 bytes provides long/double alignment.
1937cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchistatic constexpr size_t kValgrindRedZoneBytes = 8;
1947cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
1957cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi// A specialization of DlMallocSpace/RosAllocSpace that provides information to valgrind wrt allocations.
1967cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchitemplate <typename BaseMallocSpaceType, typename AllocatorType>
1977cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchiclass ValgrindMallocSpace : public BaseMallocSpaceType {
1987cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi public:
1997cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, size_t* bytes_allocated) {
2007cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    void* obj_with_rdz = BaseMallocSpaceType::AllocWithGrowth(self, num_bytes + 2 * kValgrindRedZoneBytes,
2017cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi                                                              bytes_allocated);
2027cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    if (obj_with_rdz == NULL) {
2037cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi      return NULL;
2047cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    }
2057cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    mirror::Object* result = reinterpret_cast<mirror::Object*>(
2067cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi        reinterpret_cast<byte*>(obj_with_rdz) + kValgrindRedZoneBytes);
2077cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    // Make redzones as no access.
2087cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    VALGRIND_MAKE_MEM_NOACCESS(obj_with_rdz, kValgrindRedZoneBytes);
2097cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    VALGRIND_MAKE_MEM_NOACCESS(reinterpret_cast<byte*>(result) + num_bytes, kValgrindRedZoneBytes);
2107cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    return result;
2117cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  }
2127cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
2137cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated) {
2147cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    void* obj_with_rdz = BaseMallocSpaceType::Alloc(self, num_bytes + 2 * kValgrindRedZoneBytes,
2157cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi                                                    bytes_allocated);
2167cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    if (obj_with_rdz == NULL) {
2177cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi     return NULL;
2187cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    }
2197cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    mirror::Object* result = reinterpret_cast<mirror::Object*>(
2207cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi        reinterpret_cast<byte*>(obj_with_rdz) + kValgrindRedZoneBytes);
2217cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    // Make redzones as no access.
2227cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    VALGRIND_MAKE_MEM_NOACCESS(obj_with_rdz, kValgrindRedZoneBytes);
2237cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    VALGRIND_MAKE_MEM_NOACCESS(reinterpret_cast<byte*>(result) + num_bytes, kValgrindRedZoneBytes);
2247cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    return result;
2257cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  }
2267cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
2277cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  virtual size_t AllocationSize(const mirror::Object* obj) {
2287cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    size_t result = BaseMallocSpaceType::AllocationSize(reinterpret_cast<const mirror::Object*>(
2297cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi        reinterpret_cast<const byte*>(obj) - kValgrindRedZoneBytes));
2307cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    return result - 2 * kValgrindRedZoneBytes;
2317cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  }
2327cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
2337cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  virtual size_t Free(Thread* self, mirror::Object* ptr) {
2347cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    void* obj_after_rdz = reinterpret_cast<void*>(ptr);
2357cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    void* obj_with_rdz = reinterpret_cast<byte*>(obj_after_rdz) - kValgrindRedZoneBytes;
2367cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    // Make redzones undefined.
2377cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    size_t allocation_size = BaseMallocSpaceType::AllocationSize(
2387cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi        reinterpret_cast<mirror::Object*>(obj_with_rdz));
2397cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    VALGRIND_MAKE_MEM_UNDEFINED(obj_with_rdz, allocation_size);
2407cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    size_t freed = BaseMallocSpaceType::Free(self, reinterpret_cast<mirror::Object*>(obj_with_rdz));
2417cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    return freed - 2 * kValgrindRedZoneBytes;
2427cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  }
2437cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
2447cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) {
2457cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    size_t freed = 0;
2467cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    for (size_t i = 0; i < num_ptrs; i++) {
2477cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi      freed += Free(self, ptrs[i]);
2487cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    }
2497cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    return freed;
2507cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  }
2517cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
2527cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  ValgrindMallocSpace(const std::string& name, MemMap* mem_map, AllocatorType allocator, byte* begin,
2537cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi                      byte* end, byte* limit, size_t growth_limit, size_t initial_size) :
2547cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi      BaseMallocSpaceType(name, mem_map, allocator, begin, end, limit, growth_limit) {
2557cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi    VALGRIND_MAKE_MEM_UNDEFINED(mem_map->Begin() + initial_size, mem_map->Size() - initial_size);
2567cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  }
2577cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
2587cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  virtual ~ValgrindMallocSpace() {
2597cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  }
2607cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
2617cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi private:
2627cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi  DISALLOW_COPY_AND_ASSIGN(ValgrindMallocSpace);
2637cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi};
2647cb7bbcfffb2716ef8d68ecb747954ec42c4bdc5Hiroshi Yamauchi
265cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi}  // namespace space
266cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi}  // namespace gc
267cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi}  // namespace art
268cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
269e5eedcb4a634246d1f912992853441f715d705ccHiroshi Yamauchi#endif  // ART_RUNTIME_GC_SPACE_MALLOC_SPACE_H_
270