/*
 * 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_LIBDEXFILE_DEX_COMPACT_DEX_FILE_H_
#define ART_LIBDEXFILE_DEX_COMPACT_DEX_FILE_H_

#include <memory>

#include "base/casts.h"
#include "dex/compact_offset_table.h"
#include "dex_file.h"

namespace art {

// CompactDex is a currently ART internal dex file format that aims to reduce storage/RAM usage.
class CompactDexFile : public DexFile {
 public:
  static constexpr uint8_t kDexMagic[kDexMagicSize] = { 'c', 'd', 'e', 'x' };
  // Last change: remove code item deduping.
  static constexpr uint8_t kDexMagicVersion[] = {'0', '0', '1', '\0'};

  enum class FeatureFlags : uint32_t {
    kDefaultMethods = 0x1,
  };

  class Header : public DexFile::Header {
   public:
    static const Header* At(const void* at) {
      return reinterpret_cast<const Header*>(at);
    }

    uint32_t GetFeatureFlags() const {
      return feature_flags_;
    }

    uint32_t GetDataOffset() const {
      return data_off_;
    }

    uint32_t GetDataSize() const {
      return data_size_;
    }

    // Range of the shared data section owned by the dex file. Owned in this context refers to data
    // for this DEX that was not deduplicated to another DEX.
    uint32_t OwnedDataBegin() const {
      return owned_data_begin_;
    }

    uint32_t OwnedDataEnd() const {
      return owned_data_end_;
    }

   private:
    uint32_t feature_flags_ = 0u;

    // Position in the compact dex file for the debug info table data starts.
    uint32_t debug_info_offsets_pos_ = 0u;

    // Offset into the debug info table data where the lookup table is.
    uint32_t debug_info_offsets_table_offset_ = 0u;

    // Base offset of where debug info starts in the dex file.
    uint32_t debug_info_base_ = 0u;

    // Range of the shared data section owned by the dex file.
    uint32_t owned_data_begin_ = 0u;
    uint32_t owned_data_end_ = 0u;

    friend class CompactDexFile;
    friend class CompactDexWriter;
  };

  // Like the standard code item except without a debug info offset. Each code item may have a
  // preheader to encode large methods. In 99% of cases, the preheader is not used. This enables
  // smaller size with a good fast path case in the accessors.
  struct CodeItem : public dex::CodeItem {
    static constexpr size_t kAlignment = sizeof(uint16_t);
    // Max preheader size in uint16_ts.
    static constexpr size_t kMaxPreHeaderSize = 6;

    static constexpr size_t FieldsOffset() {
      return OFFSETOF_MEMBER(CodeItem, fields_);
    }

    static constexpr size_t InsnsCountAndFlagsOffset() {
      return OFFSETOF_MEMBER(CodeItem, insns_count_and_flags_);
    }

    static constexpr size_t InsnsOffset() {
      return OFFSETOF_MEMBER(CodeItem, insns_);
    }

    static constexpr size_t kRegistersSizeShift = 12;
    static constexpr size_t kInsSizeShift = 8;
    static constexpr size_t kOutsSizeShift = 4;
    static constexpr size_t kTriesSizeSizeShift = 0;
    static constexpr uint16_t kBitPreHeaderRegistersSize = 0;
    static constexpr uint16_t kBitPreHeaderInsSize = 1;
    static constexpr uint16_t kBitPreHeaderOutsSize = 2;
    static constexpr uint16_t kBitPreHeaderTriesSize = 3;
    static constexpr uint16_t kBitPreHeaderInsnsSize = 4;
    static constexpr uint16_t kFlagPreHeaderRegistersSize = 0x1 << kBitPreHeaderRegistersSize;
    static constexpr uint16_t kFlagPreHeaderInsSize = 0x1 << kBitPreHeaderInsSize;
    static constexpr uint16_t kFlagPreHeaderOutsSize = 0x1 << kBitPreHeaderOutsSize;
    static constexpr uint16_t kFlagPreHeaderTriesSize = 0x1 << kBitPreHeaderTriesSize;
    static constexpr uint16_t kFlagPreHeaderInsnsSize = 0x1 << kBitPreHeaderInsnsSize;
    static constexpr size_t kInsnsSizeShift = 5;
    static constexpr size_t kInsnsSizeBits = sizeof(uint16_t) * kBitsPerByte -  kInsnsSizeShift;

   private:
    CodeItem() = default;

    // Combined preheader flags for fast testing if we need to go slow path.
    static constexpr uint16_t kFlagPreHeaderCombined =
        kFlagPreHeaderRegistersSize |
        kFlagPreHeaderInsSize |
        kFlagPreHeaderOutsSize |
        kFlagPreHeaderTriesSize |
        kFlagPreHeaderInsnsSize;

    // Create a code item and associated preheader if required based on field values.
    // Returns the start of the preheader. The preheader buffer must be at least as large as
    // kMaxPreHeaderSize;
    uint16_t* Create(uint16_t registers_size,
                     uint16_t ins_size,
                     uint16_t outs_size,
                     uint16_t tries_size,
                     uint32_t insns_size_in_code_units,
                     uint16_t* out_preheader) {
      // Dex verification ensures that registers size > ins_size, so we can subtract the registers
      // size accordingly to reduce how often we need to use the preheader.
      DCHECK_GE(registers_size, ins_size);
      registers_size -= ins_size;
      fields_ = (registers_size & 0xF) << kRegistersSizeShift;
      fields_ |= (ins_size & 0xF) << kInsSizeShift;
      fields_ |= (outs_size & 0xF) << kOutsSizeShift;
      fields_ |= (tries_size & 0xF) << kTriesSizeSizeShift;
      registers_size &= ~0xF;
      ins_size &= ~0xF;
      outs_size &= ~0xF;
      tries_size &= ~0xF;
      insns_count_and_flags_ = 0;
      const size_t masked_count = insns_size_in_code_units & ((1 << kInsnsSizeBits) - 1);
      insns_count_and_flags_ |= masked_count << kInsnsSizeShift;
      insns_size_in_code_units -= masked_count;

      // Since the preheader case is rare (1% of code items), use a suboptimally large but fast
      // decoding format.
      if (insns_size_in_code_units != 0) {
        insns_count_and_flags_ |= kFlagPreHeaderInsnsSize;
        --out_preheader;
        *out_preheader = static_cast<uint16_t>(insns_size_in_code_units);
        --out_preheader;
        *out_preheader = static_cast<uint16_t>(insns_size_in_code_units >> 16);
      }
      auto preheader_encode = [&](uint16_t size, uint16_t flag) {
        if (size != 0) {
          insns_count_and_flags_ |= flag;
          --out_preheader;
          *out_preheader = size;
        }
      };
      preheader_encode(registers_size, kFlagPreHeaderRegistersSize);
      preheader_encode(ins_size, kFlagPreHeaderInsSize);
      preheader_encode(outs_size, kFlagPreHeaderOutsSize);
      preheader_encode(tries_size, kFlagPreHeaderTriesSize);
      return out_preheader;
    }

    ALWAYS_INLINE bool HasPreHeader(uint16_t flag) const {
      return (insns_count_and_flags_ & flag) != 0;
    }

    // Return true if the code item has any preheaders.
    ALWAYS_INLINE static bool HasAnyPreHeader(uint16_t insns_count_and_flags) {
      return (insns_count_and_flags & kFlagPreHeaderCombined) != 0;
    }

    ALWAYS_INLINE uint16_t* GetPreHeader() {
      return reinterpret_cast<uint16_t*>(this);
    }

    ALWAYS_INLINE const uint16_t* GetPreHeader() const {
      return reinterpret_cast<const uint16_t*>(this);
    }

    // Decode fields and read the preheader if necessary. If kDecodeOnlyInstructionCount is
    // specified then only the instruction count is decoded.
    template <bool kDecodeOnlyInstructionCount>
    ALWAYS_INLINE void DecodeFields(uint32_t* insns_count,
                                    uint16_t* registers_size,
                                    uint16_t* ins_size,
                                    uint16_t* outs_size,
                                    uint16_t* tries_size) const {
      *insns_count = insns_count_and_flags_ >> kInsnsSizeShift;
      if (!kDecodeOnlyInstructionCount) {
        const uint16_t fields = fields_;
        *registers_size = (fields >> kRegistersSizeShift) & 0xF;
        *ins_size = (fields >> kInsSizeShift) & 0xF;
        *outs_size = (fields >> kOutsSizeShift) & 0xF;
        *tries_size = (fields >> kTriesSizeSizeShift) & 0xF;
      }
      if (UNLIKELY(HasAnyPreHeader(insns_count_and_flags_))) {
        const uint16_t* preheader = GetPreHeader();
        if (HasPreHeader(kFlagPreHeaderInsnsSize)) {
          --preheader;
          *insns_count += static_cast<uint32_t>(*preheader);
          --preheader;
          *insns_count += static_cast<uint32_t>(*preheader) << 16;
        }
        if (!kDecodeOnlyInstructionCount) {
          if (HasPreHeader(kFlagPreHeaderRegistersSize)) {
            --preheader;
            *registers_size += preheader[0];
          }
          if (HasPreHeader(kFlagPreHeaderInsSize)) {
            --preheader;
            *ins_size += preheader[0];
          }
          if (HasPreHeader(kFlagPreHeaderOutsSize)) {
            --preheader;
            *outs_size += preheader[0];
          }
          if (HasPreHeader(kFlagPreHeaderTriesSize)) {
            --preheader;
            *tries_size += preheader[0];
          }
        }
      }
      if (!kDecodeOnlyInstructionCount) {
        *registers_size += *ins_size;
      }
    }

    // Packed code item data, 4 bits each: [registers_size, ins_size, outs_size, tries_size]
    uint16_t fields_;

    // 5 bits for if either of the fields required preheader extension, 11 bits for the number of
    // instruction code units.
    uint16_t insns_count_and_flags_;

    uint16_t insns_[1];                  // actual array of bytecode.

    ART_FRIEND_TEST(CodeItemAccessorsTest, TestDexInstructionsAccessor);
    ART_FRIEND_TEST(CompactDexFileTest, CodeItemFields);
    friend class CodeItemDataAccessor;
    friend class CodeItemDebugInfoAccessor;
    friend class CodeItemInstructionAccessor;
    friend class CompactDexFile;
    friend class CompactDexWriter;
    DISALLOW_COPY_AND_ASSIGN(CodeItem);
  };

  // Write the compact dex specific magic.
  static void WriteMagic(uint8_t* magic);

  // Write the current version, note that the input is the address of the magic.
  static void WriteCurrentVersion(uint8_t* magic);

  // Returns true if the byte string points to the magic value.
  static bool IsMagicValid(const uint8_t* magic);
  bool IsMagicValid() const override;

  // Returns true if the byte string after the magic is the correct value.
  static bool IsVersionValid(const uint8_t* magic);
  bool IsVersionValid() const override;

  // TODO This is completely a guess. We really need to do better. b/72402467
  // We ask for 64 megabytes which should be big enough for any realistic dex file.
  size_t GetDequickenedSize() const override {
    return 64 * MB;
  }

  const Header& GetHeader() const {
    return down_cast<const Header&>(DexFile::GetHeader());
  }

  bool SupportsDefaultMethods() const override;

  uint32_t GetCodeItemSize(const dex::CodeItem& item) const override;

  uint32_t GetDebugInfoOffset(uint32_t dex_method_index) const {
    return debug_info_offsets_.GetOffset(dex_method_index);
  }

  static uint32_t CalculateChecksum(const uint8_t* base_begin,
                                    size_t base_size,
                                    const uint8_t* data_begin,
                                    size_t data_size);
  uint32_t CalculateChecksum() const override;

 private:
  CompactDexFile(const uint8_t* base,
                 size_t size,
                 const std::string& location,
                 uint32_t location_checksum,
                 const OatDexFile* oat_dex_file,
                 // Shared since several dex files may be stored in the same logical container.
                 std::shared_ptr<DexFileContainer> container);

  CompactOffsetTable::Accessor debug_info_offsets_;

  friend class DexFile;
  friend class DexFileLoader;
  DISALLOW_COPY_AND_ASSIGN(CompactDexFile);
};

}  // namespace art

#endif  // ART_LIBDEXFILE_DEX_COMPACT_DEX_FILE_H_
