/*
 * Copyright (C) 2014 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_ACCOUNTING_READ_BARRIER_TABLE_H_
#define ART_RUNTIME_GC_ACCOUNTING_READ_BARRIER_TABLE_H_

#include <sys/mman.h>  // For the PROT_* and MAP_* constants.

#include "base/bit_utils.h"
#include "base/locks.h"
#include "base/mem_map.h"
#include "gc/space/space.h"
#include "runtime_globals.h"

namespace art HIDDEN {
namespace gc {
namespace accounting {

// Used to decide whether to take the read barrier fast/slow paths for
// kUseTableLookupReadBarrier. If an entry is set, take the read
// barrier slow path. There's an entry per region.
class ReadBarrierTable {
 public:
  ReadBarrierTable() {
    size_t capacity = static_cast<size_t>(kHeapCapacity / kRegionSize);
    DCHECK_EQ(kHeapCapacity / kRegionSize,
              static_cast<uint64_t>(static_cast<size_t>(kHeapCapacity / kRegionSize)));
    std::string error_msg;
    mem_map_ = MemMap::MapAnonymous("read barrier table",
                                    capacity,
                                    PROT_READ | PROT_WRITE,
                                    /*low_4gb=*/ false,
                                    &error_msg);
    CHECK(mem_map_.IsValid() && mem_map_.Begin() != nullptr)
        << "couldn't allocate read barrier table: " << error_msg;
  }
  void ClearForSpace(space::ContinuousSpace* space) {
    uint8_t* entry_start = EntryFromAddr(space->Begin());
    uint8_t* entry_end = EntryFromAddr(space->Limit());
    memset(reinterpret_cast<void*>(entry_start), 0, entry_end - entry_start);
  }
  void Clear(uint8_t* start_addr, uint8_t* end_addr) {
    DCHECK(IsValidHeapAddr(start_addr)) << start_addr;
    DCHECK(IsValidHeapAddr(end_addr)) << end_addr;
    DCHECK_ALIGNED(start_addr, kRegionSize);
    DCHECK_ALIGNED(end_addr, kRegionSize);
    uint8_t* entry_start = EntryFromAddr(start_addr);
    uint8_t* entry_end = EntryFromAddr(end_addr);
    memset(reinterpret_cast<void*>(entry_start), 0, entry_end - entry_start);
  }
  bool IsSet(const void* heap_addr) const {
    DCHECK(IsValidHeapAddr(heap_addr)) << heap_addr;
    uint8_t entry_value = *EntryFromAddr(heap_addr);
    DCHECK(entry_value == 0 || entry_value == kSetEntryValue);
    return entry_value == kSetEntryValue;
  }
  void ClearAll() {
    mem_map_.MadviseDontNeedAndZero();
  }
  void SetAll() {
    memset(mem_map_.Begin(), kSetEntryValue, mem_map_.Size());
  }
  bool IsAllCleared() const {
    for (uint32_t* p = reinterpret_cast<uint32_t*>(mem_map_.Begin());
         p < reinterpret_cast<uint32_t*>(mem_map_.End()); ++p) {
      if (*p != 0) {
        return false;
      }
    }
    return true;
  }

  // This should match RegionSpace::kRegionSize. static_assert'ed in concurrent_copying.h.
  static constexpr size_t kRegionSize = 256 * KB;

 private:
  static constexpr uint64_t kHeapCapacity = 4ULL * GB;  // low 4gb.
  static constexpr uint8_t kSetEntryValue = 0x01;

  uint8_t* EntryFromAddr(const void* heap_addr) const {
    DCHECK(IsValidHeapAddr(heap_addr)) << heap_addr;
    uint8_t* entry_addr = mem_map_.Begin() + reinterpret_cast<uintptr_t>(heap_addr) / kRegionSize;
    DCHECK(IsValidEntry(entry_addr)) << "heap_addr: " << heap_addr
                                     << " entry_addr: " << reinterpret_cast<void*>(entry_addr);
    return entry_addr;
  }

  bool IsValidHeapAddr(const void* heap_addr) const {
#ifdef __LP64__
    return reinterpret_cast<uint64_t>(heap_addr) < kHeapCapacity;
#else
    UNUSED(heap_addr);
    return true;
#endif
  }

  bool IsValidEntry(const uint8_t* entry_addr) const {
    uint8_t* begin = mem_map_.Begin();
    uint8_t* end = mem_map_.End();
    return entry_addr >= begin && entry_addr < end;
  }

  MemMap mem_map_;
};

}  // namespace accounting
}  // namespace gc
}  // namespace art

#endif  // ART_RUNTIME_GC_ACCOUNTING_READ_BARRIER_TABLE_H_
