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
331e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov// be overridden by a MemoryToolMallocSpace.
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,
4713735955f39b3b304c37d2b2840663c131262c18Ian Rogers                               size_t capacity, uint8_t* requested_begin, bool can_move_objects);
481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
491e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov  // Virtual to allow MemoryToolMallocSpace to intercept.
506fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes, size_t* bytes_allocated,
514460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi                                          size_t* usable_size,
524460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi                                          size_t* bytes_tl_bulk_allocated)
5390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE REQUIRES(!lock_);
541e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov  // Virtual to allow MemoryToolMallocSpace to intercept.
556fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated,
564460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi                                size_t* usable_size, size_t* bytes_tl_bulk_allocated)
5790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      OVERRIDE REQUIRES(!lock_) {
584460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi    return AllocNonvirtual(self, num_bytes, bytes_allocated, usable_size,
594460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi                           bytes_tl_bulk_allocated);
606fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
611e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov  // Virtual to allow MemoryToolMallocSpace to intercept.
626fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual size_t AllocationSize(mirror::Object* obj, size_t* usable_size) OVERRIDE {
636fac447555dc94a935b78198479cce645c837b89Ian Rogers    return AllocationSizeNonvirtual(obj, usable_size);
646fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
651e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov  // Virtual to allow MemoryToolMallocSpace to intercept.
666fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual size_t Free(Thread* self, mirror::Object* ptr) OVERRIDE
6790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!lock_)
6890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
691e13374baf7dfaf442ffbf9809c37c131d681eafEvgenii Stepanov  // Virtual to allow MemoryToolMallocSpace to intercept.
706fac447555dc94a935b78198479cce645c837b89Ian Rogers  virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) OVERRIDE
7190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!lock_)
7290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
744460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi  size_t MaxBytesBulkAllocatedFor(size_t num_bytes) OVERRIDE {
754460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi    return num_bytes;
764460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi  }
774460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi
786fac447555dc94a935b78198479cce645c837b89Ian Rogers  // DlMallocSpaces don't have thread local state.
794460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi  size_t RevokeThreadLocalBuffers(art::Thread*) OVERRIDE {
804460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi    return 0U;
816fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
824460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi  size_t RevokeAllThreadLocalBuffers() OVERRIDE {
834460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi    return 0U;
8450b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi  }
8550b2928501fe489c108472e7648ec98cdca62e10Hiroshi Yamauchi
866fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Faster non-virtual allocation path.
876fac447555dc94a935b78198479cce645c837b89Ian Rogers  mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated,
884460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi                                  size_t* usable_size, size_t* bytes_tl_bulk_allocated)
8990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!lock_);
906fac447555dc94a935b78198479cce645c837b89Ian Rogers
916fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Faster non-virtual allocation size path.
926fac447555dc94a935b78198479cce645c837b89Ian Rogers  size_t AllocationSizeNonvirtual(mirror::Object* obj, size_t* usable_size);
936fac447555dc94a935b78198479cce645c837b89Ian Rogers
94cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#ifndef NDEBUG
95cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  // Override only in the debug build.
96cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  void CheckMoreCoreForPrecondition();
97cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi#endif
981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  void* GetMspace() const {
1001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return mspace_;
1011d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
1021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1036fac447555dc94a935b78198479cce645c837b89Ian Rogers  size_t Trim() OVERRIDE;
1041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be
1061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // in use, indicated by num_bytes equaling zero.
10790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void Walk(WalkCallback callback, void* arg) OVERRIDE REQUIRES(!lock_);
1081d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
10909b07a96094086e205948717666025909a75163bHiroshi Yamauchi  // Returns the number of bytes that the space has currently obtained from the system. This is
11009b07a96094086e205948717666025909a75163bHiroshi Yamauchi  // greater or equal to the amount of live data in the space.
1116fac447555dc94a935b78198479cce645c837b89Ian Rogers  size_t GetFootprint() OVERRIDE;
11209b07a96094086e205948717666025909a75163bHiroshi Yamauchi
1131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore.
1146fac447555dc94a935b78198479cce645c837b89Ian Rogers  size_t GetFootprintLimit() OVERRIDE;
1151d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // Set the maximum number of bytes that the heap is allowed to obtain from the system via
1171d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When
1181d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow.
1196fac447555dc94a935b78198479cce645c837b89Ian Rogers  void SetFootprintLimit(size_t limit) OVERRIDE;
1201d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
121d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe  MallocSpace* CreateInstance(MemMap* mem_map, const std::string& name, void* allocator,
12213735955f39b3b304c37d2b2840663c131262c18Ian Rogers                              uint8_t* begin, uint8_t* end, uint8_t* limit, size_t growth_limit,
12331f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier                              bool can_move_objects);
1241d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1256fac447555dc94a935b78198479cce645c837b89Ian Rogers  uint64_t GetBytesAllocated() OVERRIDE;
1266fac447555dc94a935b78198479cce645c837b89Ian Rogers  uint64_t GetObjectsAllocated() OVERRIDE;
1271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
12831f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier  virtual void Clear() OVERRIDE;
1290f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartier
1306fac447555dc94a935b78198479cce645c837b89Ian Rogers  bool IsDlMallocSpace() const OVERRIDE {
131cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return true;
132cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
1336fac447555dc94a935b78198479cce645c837b89Ian Rogers
1346fac447555dc94a935b78198479cce645c837b89Ian Rogers  DlMallocSpace* AsDlMallocSpace() OVERRIDE {
135cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return this;
136cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
137cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi
138654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi  void LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) OVERRIDE
13990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
140654dd48e2230e16bfaa225decce72b52642e2f78Hiroshi Yamauchi
1411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers protected:
142d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe  DlMallocSpace(MemMap* mem_map, size_t initial_size, const std::string& name, void* mspace,
143d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe                uint8_t* begin, uint8_t* end, uint8_t* limit, size_t growth_limit,
144d7576328811e5103e99d31f834a857522cc1463fAndreas Gampe                bool can_move_objects, size_t starting_size);
1451d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private:
1476fac447555dc94a935b78198479cce645c837b89Ian Rogers  mirror::Object* AllocWithoutGrowthLocked(Thread* self, size_t num_bytes, size_t* bytes_allocated,
1484460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi                                           size_t* usable_size,
1494460a84be92b5a94ecfb5c650aef4945ab849c93Hiroshi Yamauchi                                           size_t* bytes_tl_bulk_allocated)
15090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(lock_);
1511d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1526fac447555dc94a935b78198479cce645c837b89Ian Rogers  void* CreateAllocator(void* base, size_t morecore_start, size_t initial_size,
15326d69ffc0ebc98fbc5f316d8cd3ee6ba5b2001acHiroshi Yamauchi                        size_t /*maximum_size*/, bool /*low_memory_mode*/) OVERRIDE {
154cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi    return CreateMspace(base, morecore_start, initial_size);
155cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  }
156cf58d4adf461eb9b8e84baa8019054c88cd8acc6Hiroshi Yamauchi  static void* CreateMspace(void* base, size_t morecore_start, size_t initial_size);
1570f72e4136aecaf6976fdb55916bbd7b6d5c9c77bMathieu Chartier
1581d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // The boundary tag overhead.
15913735955f39b3b304c37d2b2840663c131262c18Ian Rogers  static const size_t kChunkOverhead = sizeof(intptr_t);
1601d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1616fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Underlying malloc space.
16231f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier  void* mspace_;
1631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  friend class collector::MarkSweep;
1651d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1661d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(DlMallocSpace);
1671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
1681d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace space
1701d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace gc
1711d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace art
1721d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
173fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_
174