/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_GC_SPACE_LARGE_OBJECT_SPACE_H_
#define ART_RUNTIME_GC_SPACE_LARGE_OBJECT_SPACE_H_

#include "base/allocator.h"
#include "base/safe_map.h"
#include "base/tracking_safe_map.h"
#include "dlmalloc_space.h"
#include "space.h"
#include "thread-current-inl.h"

#include <set>
#include <vector>

namespace art HIDDEN {
namespace gc {
namespace space {

class AllocationInfo;

enum class LargeObjectSpaceType {
  kDisabled,
  kMap,
  kFreeList,
};

// Abstraction implemented by all large object spaces.
class LargeObjectSpace : public DiscontinuousSpace, public AllocSpace {
 public:
  SpaceType GetType() const override {
    return kSpaceTypeLargeObjectSpace;
  }
  void SwapBitmaps();
  void CopyLiveToMarked();
  virtual void Walk(DlMallocSpace::WalkCallback, void* arg) = 0;
  virtual ~LargeObjectSpace() {}

  uint64_t GetBytesAllocated() override {
    MutexLock mu(Thread::Current(), lock_);
    return num_bytes_allocated_;
  }
  uint64_t GetObjectsAllocated() override {
    MutexLock mu(Thread::Current(), lock_);
    return num_objects_allocated_;
  }
  uint64_t GetTotalBytesAllocated() const {
    MutexLock mu(Thread::Current(), lock_);
    return total_bytes_allocated_;
  }
  uint64_t GetTotalObjectsAllocated() const {
    MutexLock mu(Thread::Current(), lock_);
    return total_objects_allocated_;
  }
  size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) override;
  // LargeObjectSpaces don't have thread local state.
  size_t RevokeThreadLocalBuffers(art::Thread*) override {
    return 0U;
  }
  size_t RevokeAllThreadLocalBuffers() override {
    return 0U;
  }
  bool IsAllocSpace() const override {
    return true;
  }
  AllocSpace* AsAllocSpace() override {
    return this;
  }
  collector::ObjectBytePair Sweep(bool swap_bitmaps);
  bool CanMoveObjects() const override {
    return false;
  }
  // Current address at which the space begins, which may vary as the space is filled.
  uint8_t* Begin() const {
    return begin_;
  }
  // Current address at which the space ends, which may vary as the space is filled.
  uint8_t* End() const {
    return end_;
  }
  // Current size of space
  size_t Size() const {
    return End() - Begin();
  }
  // Return true if we contain the specified address.
  bool Contains(const mirror::Object* obj) const override {
    const uint8_t* byte_obj = reinterpret_cast<const uint8_t*>(obj);
    return Begin() <= byte_obj && byte_obj < End();
  }
  bool LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) override
      REQUIRES_SHARED(Locks::mutator_lock_);

  // Return true if the large object is a zygote large object. Potentially slow.
  virtual bool IsZygoteLargeObject(Thread* self, mirror::Object* obj) const = 0;
  // Called when we create the zygote space, mark all existing large objects as zygote large
  // objects. Set mark-bit if called from PreZygoteFork() for ConcurrentCopying
  // GC to avoid dirtying the first page.
  virtual void SetAllLargeObjectsAsZygoteObjects(Thread* self, bool set_mark_bit) = 0;

  virtual void ForEachMemMap(std::function<void(const MemMap&)> func) const = 0;
  // GetRangeAtomic returns Begin() and End() atomically, that is, it never returns Begin() and
  // End() from different allocations.
  virtual std::pair<uint8_t*, uint8_t*> GetBeginEndAtomic() const = 0;
  // Clamp the space size to the given capacity.
  virtual void ClampGrowthLimit(size_t capacity) = 0;

  // The way large object spaces are implemented, the object alignment has to be
  // the same as the *runtime* OS page size. However, in the future this may
  // change so it is important to use LargeObjectSpace::ObjectAlignment() rather
  // than gPageSize when appropriate.
#if defined(ART_PAGE_SIZE_AGNOSTIC)
  static ALWAYS_INLINE size_t ObjectAlignment() { return gPageSize; }
#else
  static constexpr size_t ObjectAlignment() { return kMinPageSize; }
#endif

 protected:
  explicit LargeObjectSpace(const std::string& name, uint8_t* begin, uint8_t* end,
                            const char* lock_name);
  static void SweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* arg);

  // Used to ensure mutual exclusion when the allocation spaces data structures,
  // including the allocation counters below, are being modified.
  mutable Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;

  // Number of bytes which have been allocated into the space and not yet freed. The count is also
  // included in the identically named field in Heap. Counts actual allocated (after rounding),
  // not requested, sizes. TODO: It would be cheaper to just maintain total allocated and total
  // free counts.
  uint64_t num_bytes_allocated_ GUARDED_BY(lock_);
  uint64_t num_objects_allocated_ GUARDED_BY(lock_);

  // Totals for large objects ever allocated, including those that have since been deallocated.
  // Never decremented.
  uint64_t total_bytes_allocated_ GUARDED_BY(lock_);
  uint64_t total_objects_allocated_ GUARDED_BY(lock_);

  // Begin and end, may change as more large objects are allocated.
  uint8_t* begin_;
  uint8_t* end_;

  friend class Space;

 private:
  DISALLOW_COPY_AND_ASSIGN(LargeObjectSpace);
};

// A discontinuous large object space implemented by individual mmap/munmap calls.
class LargeObjectMapSpace : public LargeObjectSpace {
 public:
  // Creates a large object space. Allocations into the large object space use memory maps instead
  // of malloc.
  static LargeObjectMapSpace* Create(const std::string& name);
  // Return the storage space required by obj.
  size_t AllocationSize(mirror::Object* obj, size_t* usable_size) override REQUIRES(!lock_);
  mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated,
                        size_t* usable_size, size_t* bytes_tl_bulk_allocated) override
      REQUIRES(!lock_);
  size_t Free(Thread* self, mirror::Object* ptr) override REQUIRES(!lock_);
  void Walk(DlMallocSpace::WalkCallback, void* arg) override REQUIRES(!lock_);
  // TODO: disabling thread safety analysis as this may be called when we already hold lock_.
  bool Contains(const mirror::Object* obj) const override NO_THREAD_SAFETY_ANALYSIS;
  void ForEachMemMap(std::function<void(const MemMap&)> func) const override REQUIRES(!lock_);
  std::pair<uint8_t*, uint8_t*> GetBeginEndAtomic() const override REQUIRES(!lock_);
  void ClampGrowthLimit(size_t capacity ATTRIBUTE_UNUSED) override {}

 protected:
  struct LargeObject {
    MemMap mem_map;
    bool is_zygote;
  };
  explicit LargeObjectMapSpace(const std::string& name);
  virtual ~LargeObjectMapSpace() {}

  bool IsZygoteLargeObject(Thread* self, mirror::Object* obj) const override REQUIRES(!lock_);
  void SetAllLargeObjectsAsZygoteObjects(Thread* self, bool set_mark_bit) override
      REQUIRES(!lock_)
      REQUIRES_SHARED(Locks::mutator_lock_);

  AllocationTrackingSafeMap<mirror::Object*, LargeObject, kAllocatorTagLOSMaps> large_objects_
      GUARDED_BY(lock_);
};

// A continuous large object space with a free-list to handle holes.
class FreeListSpace final : public LargeObjectSpace {
 public:
  virtual ~FreeListSpace();
  static FreeListSpace* Create(const std::string& name, size_t capacity);
  size_t AllocationSize(mirror::Object* obj, size_t* usable_size) override
      REQUIRES(lock_);
  mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated,
                        size_t* usable_size, size_t* bytes_tl_bulk_allocated)
      override REQUIRES(!lock_);
  size_t Free(Thread* self, mirror::Object* obj) override REQUIRES(!lock_);
  void Walk(DlMallocSpace::WalkCallback callback, void* arg) override REQUIRES(!lock_);
  void Dump(std::ostream& os) const override REQUIRES(!lock_);
  void ForEachMemMap(std::function<void(const MemMap&)> func) const override REQUIRES(!lock_);
  std::pair<uint8_t*, uint8_t*> GetBeginEndAtomic() const override REQUIRES(!lock_);
  void ClampGrowthLimit(size_t capacity) override REQUIRES(!lock_);

 protected:
  FreeListSpace(const std::string& name, MemMap&& mem_map, uint8_t* begin, uint8_t* end);
  size_t GetSlotIndexForAddress(uintptr_t address) const {
    DCHECK(Contains(reinterpret_cast<mirror::Object*>(address)));
    return (address - reinterpret_cast<uintptr_t>(Begin())) / ObjectAlignment();
  }
  size_t GetSlotIndexForAllocationInfo(const AllocationInfo* info) const;
  AllocationInfo* GetAllocationInfoForAddress(uintptr_t address);
  const AllocationInfo* GetAllocationInfoForAddress(uintptr_t address) const;
  uintptr_t GetAllocationAddressForSlot(size_t slot) const {
    return reinterpret_cast<uintptr_t>(Begin()) + slot * ObjectAlignment();
  }
  uintptr_t GetAddressForAllocationInfo(const AllocationInfo* info) const {
    return GetAllocationAddressForSlot(GetSlotIndexForAllocationInfo(info));
  }
  // Removes header from the free blocks set by finding the corresponding iterator and erasing it.
  void RemoveFreePrev(AllocationInfo* info) REQUIRES(lock_);
  bool IsZygoteLargeObject(Thread* self, mirror::Object* obj) const override;
  void SetAllLargeObjectsAsZygoteObjects(Thread* self, bool set_mark_bit) override
      REQUIRES(!lock_)
      REQUIRES_SHARED(Locks::mutator_lock_);

  class SortByPrevFree {
   public:
    bool operator()(const AllocationInfo* a, const AllocationInfo* b) const;
  };
  using FreeBlocks = std::set<AllocationInfo*,
                              SortByPrevFree,
                              TrackingAllocator<AllocationInfo*, kAllocatorTagLOSFreeList>>;

  // There is not footer for any allocations at the end of the space, so we keep track of how much
  // free space there is at the end manually.
  MemMap mem_map_;
  // Side table for allocation info, one per page.
  MemMap allocation_info_map_;
  AllocationInfo* allocation_info_;

  // Free bytes at the end of the space.
  size_t free_end_ GUARDED_BY(lock_);
  FreeBlocks free_blocks_ GUARDED_BY(lock_);
};

}  // namespace space
}  // namespace gc
}  // namespace art

#endif  // ART_RUNTIME_GC_SPACE_LARGE_OBJECT_SPACE_H_
