/*
 * Copyright (C) 2015 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.
 */

#include <gtest/gtest.h>

#include "compiled_method_storage.h"
#include "compiled_method.h"
#include "compiler_driver.h"
#include "compiler_options.h"
#include "dex/verification_results.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"

namespace art {

TEST(CompiledMethodStorage, Deduplicate) {
  CompilerOptions compiler_options;
  VerificationResults verification_results(&compiler_options);
  DexFileToMethodInlinerMap method_inliner_map;
  CompilerDriver driver(&compiler_options,
                        &verification_results,
                        &method_inliner_map,
                        Compiler::kOptimizing,
                        /* instruction_set_ */ kNone,
                        /* instruction_set_features */ nullptr,
                        /* boot_image */ false,
                        /* image_classes */ nullptr,
                        /* compiled_classes */ nullptr,
                        /* compiled_methods */ nullptr,
                        /* thread_count */ 1u,
                        /* dump_stats */ false,
                        /* dump_passes */ false,
                        /* timer */ nullptr,
                        /* swap_fd */ -1,
                        /* profile_compilation_info */ nullptr);
  CompiledMethodStorage* storage = driver.GetCompiledMethodStorage();

  ASSERT_TRUE(storage->DedupeEnabled());  // The default.

  const uint8_t raw_code1[] = { 1u, 2u, 3u };
  const uint8_t raw_code2[] = { 4u, 3u, 2u, 1u };
  ArrayRef<const uint8_t> code[] = {
      ArrayRef<const uint8_t>(raw_code1),
      ArrayRef<const uint8_t>(raw_code2),
  };
  const SrcMapElem raw_src_map1[] = { { 1u, 2u }, { 3u, 4u }, { 5u, 6u } };
  const SrcMapElem raw_src_map2[] = { { 8u, 7u }, { 6u, 5u }, { 4u, 3u }, { 2u, 1u } };
  ArrayRef<const SrcMapElem> src_map[] = {
      ArrayRef<const SrcMapElem>(raw_src_map1),
      ArrayRef<const SrcMapElem>(raw_src_map2),
  };
  const uint8_t raw_mapping_table1[] = { 5, 6, 7 };
  const uint8_t raw_mapping_table2[] = { 7, 6, 5, 4 };
  ArrayRef<const uint8_t> mapping_table[] = {
      ArrayRef<const uint8_t>(raw_mapping_table1),
      ArrayRef<const uint8_t>(raw_mapping_table2),
  };
  const uint8_t raw_vmap_table1[] = { 2, 4, 6 };
  const uint8_t raw_vmap_table2[] = { 7, 5, 3, 1 };
  ArrayRef<const uint8_t> vmap_table[] = {
      ArrayRef<const uint8_t>(raw_vmap_table1),
      ArrayRef<const uint8_t>(raw_vmap_table2),
  };
  const uint8_t raw_gc_map1[] = { 9, 8, 7 };
  const uint8_t raw_gc_map2[] = { 6, 7, 8, 9 };
  ArrayRef<const uint8_t> gc_map[] = {
      ArrayRef<const uint8_t>(raw_gc_map1),
      ArrayRef<const uint8_t>(raw_gc_map2),
  };
  const uint8_t raw_cfi_info1[] = { 1, 3, 5 };
  const uint8_t raw_cfi_info2[] = { 8, 6, 4, 2 };
  ArrayRef<const uint8_t> cfi_info[] = {
      ArrayRef<const uint8_t>(raw_cfi_info1),
      ArrayRef<const uint8_t>(raw_cfi_info2),
  };
  const LinkerPatch raw_patches1[] = {
      LinkerPatch::CodePatch(0u, nullptr, 1u),
      LinkerPatch::MethodPatch(4u, nullptr, 1u),
  };
  const LinkerPatch raw_patches2[] = {
      LinkerPatch::CodePatch(0u, nullptr, 1u),
      LinkerPatch::MethodPatch(4u, nullptr, 2u),
  };
  ArrayRef<const LinkerPatch> patches[] = {
      ArrayRef<const LinkerPatch>(raw_patches1),
      ArrayRef<const LinkerPatch>(raw_patches2),
  };

  std::vector<CompiledMethod*> compiled_methods;
  compiled_methods.reserve(1u << 7);
  for (auto&& c : code) {
    for (auto&& s : src_map) {
      for (auto&& m : mapping_table) {
        for (auto&& v : vmap_table) {
          for (auto&& g : gc_map) {
            for (auto&& f : cfi_info) {
              for (auto&& p : patches) {
                compiled_methods.push_back(CompiledMethod::SwapAllocCompiledMethod(
                        &driver, kNone, c, 0u, 0u, 0u, s, m, v, g, f, p));
              }
            }
          }
        }
      }
    }
  }
  constexpr size_t code_bit = 1u << 6;
  constexpr size_t src_map_bit = 1u << 5;
  constexpr size_t mapping_table_bit = 1u << 4;
  constexpr size_t vmap_table_bit = 1u << 3;
  constexpr size_t gc_map_bit = 1u << 2;
  constexpr size_t cfi_info_bit = 1u << 1;
  constexpr size_t patches_bit = 1u << 0;
  CHECK_EQ(compiled_methods.size(), 1u << 7);
  for (size_t i = 0; i != compiled_methods.size(); ++i) {
    for (size_t j = 0; j != compiled_methods.size(); ++j) {
      CompiledMethod* lhs = compiled_methods[i];
      CompiledMethod* rhs = compiled_methods[j];
      bool same_code = ((i ^ j) & code_bit) == 0u;
      bool same_src_map = ((i ^ j) & src_map_bit) == 0u;
      bool same_mapping_table = ((i ^ j) & mapping_table_bit) == 0u;
      bool same_vmap_table = ((i ^ j) & vmap_table_bit) == 0u;
      bool same_gc_map = ((i ^ j) & gc_map_bit) == 0u;
      bool same_cfi_info = ((i ^ j) & cfi_info_bit) == 0u;
      bool same_patches = ((i ^ j) & patches_bit) == 0u;
      ASSERT_EQ(same_code, lhs->GetQuickCode().data() == rhs->GetQuickCode().data())
          << i << " " << j;
      ASSERT_EQ(same_src_map, lhs->GetSrcMappingTable().data() == rhs->GetSrcMappingTable().data())
          << i << " " << j;
      ASSERT_EQ(same_mapping_table, lhs->GetMappingTable().data() == rhs->GetMappingTable().data())
          << i << " " << j;
      ASSERT_EQ(same_vmap_table, lhs->GetVmapTable().data() == rhs->GetVmapTable().data())
          << i << " " << j;
      ASSERT_EQ(same_gc_map, lhs->GetGcMap().data() == rhs->GetGcMap().data())
          << i << " " << j;
      ASSERT_EQ(same_cfi_info, lhs->GetCFIInfo().data() == rhs->GetCFIInfo().data())
          << i << " " << j;
      ASSERT_EQ(same_patches, lhs->GetPatches().data() == rhs->GetPatches().data())
          << i << " " << j;
    }
  }
  for (CompiledMethod* method : compiled_methods) {
    CompiledMethod::ReleaseSwapAllocatedCompiledMethod(&driver, method);
  }
}

}  // namespace art
