/*
 * Copyright (C) 2017 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_DEX_FILE_LAYOUT_H_
#define ART_RUNTIME_DEX_FILE_LAYOUT_H_

#include <algorithm>
#include <cstdint>
#include <iosfwd>

#include "base/logging.h"

namespace art {

class DexFile;

enum class LayoutType : uint8_t {
  // Layout of things that are hot (commonly accessed), these should be pinned or madvised will
  // need.
  kLayoutTypeHot,
  // Layout of things that are randomly used. These should be advised to random access.
  // Without layout, this is the default mode when loading a dex file.
  kLayoutTypeSometimesUsed,
  // Layout of things that are only used during startup, these can be madvised after launch.
  kLayoutTypeStartupOnly,
  // Layout of things that are needed probably only once (class initializers). These can be
  // madvised during trim events.
  kLayoutTypeUsedOnce,
  // Layout of things that are thought to be unused. These things should be advised to random
  // access.
  kLayoutTypeUnused,
  // Unused value, just the number of elements in the enum.
  kLayoutTypeCount,
};
std::ostream& operator<<(std::ostream& os, const LayoutType& collector_type);

// Return the "best" layout option if the same item has multiple different layouts.
static inline LayoutType MergeLayoutType(LayoutType a, LayoutType b) {
  return std::min(a, b);
}

enum class MadviseState : uint8_t {
  // Madvise based on a file that was just loaded.
  kMadviseStateAtLoad,
  // Madvise based after launch is finished.
  kMadviseStateFinishedLaunch,
  // Trim by madvising code that is unlikely to be too important in the future.
  kMadviseStateFinishedTrim,
};
std::ostream& operator<<(std::ostream& os, const MadviseState& collector_type);

// A dex layout section such as code items or strings. Each section is composed of subsections
// that are laid out adjacently to each other such as (hot, unused, startup, etc...).
class DexLayoutSection {
 public:
  // A subsection is a a continuous range of dex file that is all part of the same layout hint.
  class Subsection {
   public:
    // Use uint32_t to handle 32/64 bit cross compilation.
    uint32_t start_offset_ = 0u;
    uint32_t end_offset_ = 0u;

    bool Contains(uint32_t offset) const {
      return start_offset_ <= offset && offset < end_offset_;
    }

    bool Size() const {
      DCHECK_LE(start_offset_, end_offset_);
      return end_offset_ - start_offset_;
    }

    void CombineSection(uint32_t start_offset, uint32_t end_offset) {
      DCHECK_LT(start_offset, end_offset);
      if (start_offset_ == end_offset_) {
        start_offset_ = start_offset;
        end_offset_ = end_offset;
      } else  {
        start_offset_ = std::min(start_offset_, start_offset);
        end_offset_ = std::max(end_offset_, end_offset);
      }
    }

    void Madvise(const DexFile* dex_file, int advice) const;
  };

  Subsection parts_[static_cast<size_t>(LayoutType::kLayoutTypeCount)];
};

// A set of dex layout sections, currently there is only one section for code and one for strings.
class DexLayoutSections {
 public:
  enum class SectionType : uint8_t {
    kSectionTypeCode,
    kSectionTypeStrings,
    kSectionCount,
  };

  // Advise access about the dex file based on layout. The caller is expected to have already
  // madvised to MADV_RANDOM.
  void Madvise(const DexFile* dex_file, MadviseState state) const;

  DexLayoutSection sections_[static_cast<size_t>(SectionType::kSectionCount)];
};

std::ostream& operator<<(std::ostream& os, const DexLayoutSections::SectionType& collector_type);
std::ostream& operator<<(std::ostream& os, const DexLayoutSection& section);
std::ostream& operator<<(std::ostream& os, const DexLayoutSections& sections);

}  // namespace art

#endif  // ART_RUNTIME_DEX_FILE_LAYOUT_H_
