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_DLMALLOC_SPACE_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_
191d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
20cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#include "malloc_space.h"
211d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "space.h"
221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
231d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace art {
241d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace gc {
251d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
261d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace collector {
271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  class MarkSweep;
281d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace collector
291d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
301d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace space {
311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
326fac447555dc94a935b78198479cce645c837b89Ian Rogers// An alloc space is a space where objects may be allocated and garbage collected. Not final as may
336fac447555dc94a935b78198479cce645c837b89Ian Rogers// be overridden by a ValgrindMallocSpace.
34cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchiclass DlMallocSpace : public MallocSpace {
351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public:
36e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  // Create a DlMallocSpace from an existing mem_map.
37e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier  static DlMallocSpace* CreateFromMemMap(MemMap* mem_map, const std::string& name,
38e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier                                         size_t starting_size, size_t initial_size,
3931f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier                                         size_t growth_limit, size_t capacity,
4031f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier                                         bool can_move_objects);
41e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier
42cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Create a DlMallocSpace with the requested sizes. The requested
431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // base address is not guaranteed to be granted, if it is required,
44cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // the caller should call Begin on the returned space to confirm the
45cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // request was granted.
461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  static DlMallocSpace* Create(const std::string& name, size_t initial_size, size_t growth_limit,
4731f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier                               size_t capacity, byte* requested_begin, bool can_move_objects);
481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
496fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Virtual to allow ValgrindMallocSpace to intercept.
506fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, size_t* bytes_allocated,
516fac447555dc94a935b78198479cce645c837b89Ian Rogers                                          size_t* usable_size) OVERRIDE LOCKS_EXCLUDED(lock_);
526fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Virtual to allow ValgrindMallocSpace to intercept.
536fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated,
546fac447555dc94a935b78198479cce645c837b89Ian Rogers                        size_t* usable_size) OVERRIDE LOCKS_EXCLUDED(lock_) {
556fac447555dc94a935b78198479cce645c837b89Ian Rogers    return AllocNonvirtual(self, num_bytes, bytes_allocated, usable_size);
566fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
576fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Virtual to allow ValgrindMallocSpace to intercept.
586fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual size_t AllocationSize(mirror::Object* obj, size_t* usable_size) OVERRIDE {
596fac447555dc94a935b78198479cce645c837b89Ian Rogers    return AllocationSizeNonvirtual(obj, usable_size);
606fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
616fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Virtual to allow ValgrindMallocSpace to intercept.
626fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual size_t Free(Thread* self, mirror::Object* ptr) OVERRIDE
636fac447555dc94a935b78198479cce645c837b89Ian Rogers      LOCKS_EXCLUDED(lock_)
64ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
656fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Virtual to allow ValgrindMallocSpace to intercept.
666fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) OVERRIDE
676fac447555dc94a935b78198479cce645c837b89Ian Rogers      LOCKS_EXCLUDED(lock_)
68ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
706fac447555dc94a935b78198479cce645c837b89Ian Rogers  // DlMallocSpaces don't have thread local state.
716fac447555dc94a935b78198479cce645c837b89Ian Rogers  void RevokeThreadLocalBuffers(art::Thread*) OVERRIDE {
726fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
736fac447555dc94a935b78198479cce645c837b89Ian Rogers  void RevokeAllThreadLocalBuffers() OVERRIDE {
7450b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi  }
7550b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi
766fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Faster non-virtual allocation path.
776fac447555dc94a935b78198479cce645c837b89Ian Rogers  mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated,
786fac447555dc94a935b78198479cce645c837b89Ian Rogers                                  size_t* usable_size) LOCKS_EXCLUDED(lock_);
796fac447555dc94a935b78198479cce645c837b89Ian Rogers
806fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Faster non-virtual allocation size path.
816fac447555dc94a935b78198479cce645c837b89Ian Rogers  size_t AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size);
826fac447555dc94a935b78198479cce645c837b89Ian Rogers
83cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#ifndef NDEBUG
84cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Override only in the debug build.
85cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void CheckMoreCoreForPrecondition();
86cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#endif
871d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
881d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  void* GetMspace() const {
891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return mspace_;
901d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
911d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
926fac447555dc94a935b78198479cce645c837b89Ian Rogers  size_t Trim() OVERRIDE;
931d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
941d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be
951d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // in use, indicated by num_bytes equaling zero.
966fac447555dc94a935b78198479cce645c837b89Ian Rogers  void Walk(WalkCallback callback, void* arg) OVERRIDE LOCKS_EXCLUDED(lock_);
971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
9809b07a96094086e205948717666025909a75163bHiroshi Yamauchi  // Returns the number of bytes that the space has currently obtained from the system. This is
9909b07a96094086e205948717666025909a75163bHiroshi Yamauchi  // greater or equal to the amount of live data in the space.
1006fac447555dc94a935b78198479cce645c837b89Ian Rogers  size_t GetFootprint() OVERRIDE;
10109b07a96094086e205948717666025909a75163bHiroshi Yamauchi
1021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore.
1036fac447555dc94a935b78198479cce645c837b89Ian Rogers  size_t GetFootprintLimit() OVERRIDE;
1041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Set the maximum number of bytes that the heap is allowed to obtain from the system via
1061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When
1071d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow.
1086fac447555dc94a935b78198479cce645c837b89Ian Rogers  void SetFootprintLimit(size_t limit) OVERRIDE;
1091d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
110cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  MallocSpace* CreateInstance(const std::string& name, MemMap* mem_map, void* allocator,
11131f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier                              byte* begin, byte* end, byte* limit, size_t growth_limit,
11231f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier                              bool can_move_objects);
1131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1146fac447555dc94a935b78198479cce645c837b89Ian Rogers  uint64_t GetBytesAllocated() OVERRIDE;
1156fac447555dc94a935b78198479cce645c837b89Ian Rogers  uint64_t GetObjectsAllocated() OVERRIDE;
1161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
11731f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier  virtual void Clear() OVERRIDE;
1180f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartier
1196fac447555dc94a935b78198479cce645c837b89Ian Rogers  bool IsDlMallocSpace() const OVERRIDE {
120cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return true;
121cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
1226fac447555dc94a935b78198479cce645c837b89Ian Rogers
1236fac447555dc94a935b78198479cce645c837b89Ian Rogers  DlMallocSpace* AsDlMallocSpace() OVERRIDE {
124cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return this;
125cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
126cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
127654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi  void LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) OVERRIDE
128654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
129654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi
1301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected:
1311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DlMallocSpace(const std::string& name, MemMap* mem_map, void* mspace, byte* begin, byte* end,
13231f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier                byte* limit, size_t growth_limit, bool can_move_objects, size_t starting_size,
13331f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier                size_t initial_size);
1341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private:
1366fac447555dc94a935b78198479cce645c837b89Ian Rogers  mirror::Object* AllocWithoutGrowthLocked(Thread* self, size_t num_bytes, size_t* bytes_allocated,
1376fac447555dc94a935b78198479cce645c837b89Ian Rogers                                           size_t* usable_size)
138cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi      EXCLUSIVE_LOCKS_REQUIRED(lock_);
1391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1406fac447555dc94a935b78198479cce645c837b89Ian Rogers  void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size,
14126d69ffc0ebc98fbc5f316d8cd3ee6ba5b2001acHiroshi Yamauchi                        size_t /*maximum_size*/, bool /*low_memory_mode*/) OVERRIDE {
142cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return CreateMspace(base, morecore_start, initial_size);
143cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
144cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  static void* CreateMspace(void* base, size_t morecore_start, size_t initial_size);
1450f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartier
1461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // The boundary tag overhead.
1471d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  static const size_t kChunkOverhead = kWordSize;
1481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1496fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Underlying malloc space.
15031f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier  void* mspace_;
1511d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1521d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  friend class collector::MarkSweep;
1531d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1541d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(DlMallocSpace);
1551d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
1561d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1571d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace space
1581d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace gc
1591d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace art
1601d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
161fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_
162