/*
 * Copyright (C) 2011 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_COMPILER_COMMON_COMPILER_TEST_H_
#define ART_COMPILER_COMMON_COMPILER_TEST_H_

#include <list>
#include <vector>

#include <jni.h>

#include "arch/instruction_set.h"
#include "arch/instruction_set_features.h"
#include "base/macros.h"
#include "common_runtime_test.h"
#include "compiler.h"
#include "oat/oat_file.h"

namespace art HIDDEN {
namespace mirror {
class ClassLoader;
}  // namespace mirror

class CompilerOptions;
class CumulativeLogger;
class DexFile;
class TimingLogger;

template<class T> class Handle;

// Export all symbols in `CommonCompilerTestImpl` for dex2oat tests.
class EXPORT CommonCompilerTestImpl {
 public:
  static std::unique_ptr<CompilerOptions> CreateCompilerOptions(InstructionSet instruction_set,
                                                                const std::string& variant);

  CommonCompilerTestImpl();
  virtual ~CommonCompilerTestImpl();

  // Create an executable copy of the code with given metadata.
  const void* MakeExecutable(ArrayRef<const uint8_t> code,
                             ArrayRef<const uint8_t> vmap_table,
                             InstructionSet instruction_set);

 protected:
  void SetUp();

  void SetUpRuntimeOptionsImpl();

  Compiler::Kind GetCompilerKind() const;
  void SetCompilerKind(Compiler::Kind compiler_kind);

  virtual CompilerFilter::Filter GetCompilerFilter() const {
    return CompilerFilter::kDefaultCompilerFilter;
  }

  void TearDown();

  void CompileMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);

  void ApplyInstructionSet();
  void OverrideInstructionSetFeatures(InstructionSet instruction_set, const std::string& variant);

  void ClearBootImageOption();

  Compiler::Kind compiler_kind_ = Compiler::kOptimizing;

  InstructionSet instruction_set_ =
      (kRuntimeISA == InstructionSet::kArm) ? InstructionSet::kThumb2 : kRuntimeISA;
  // Take the default set of instruction features from the build.
  std::unique_ptr<const InstructionSetFeatures> instruction_set_features_
      = InstructionSetFeatures::FromCppDefines();

  std::unique_ptr<CompilerOptions> compiler_options_;

 protected:
  virtual ClassLinker* GetClassLinker() = 0;
  virtual Runtime* GetRuntime() = 0;

 private:
  class CodeAndMetadata;
  class OneCompiledMethodStorage;

  std::vector<CodeAndMetadata> code_and_metadata_;
};

template <typename RuntimeBase>
class CommonCompilerTestBase : public CommonCompilerTestImpl, public RuntimeBase {
 public:
  void SetUp() override {
    RuntimeBase::SetUp();
    CommonCompilerTestImpl::SetUp();
  }
  void SetUpRuntimeOptions(RuntimeOptions* options) override {
    RuntimeBase::SetUpRuntimeOptions(options);
    CommonCompilerTestImpl::SetUpRuntimeOptionsImpl();
  }
  void TearDown() override {
    CommonCompilerTestImpl::TearDown();
    RuntimeBase::TearDown();
  }

 protected:
  ClassLinker* GetClassLinker() override {
    return RuntimeBase::class_linker_;
  }
  Runtime* GetRuntime() override {
    return RuntimeBase::runtime_.get();
  }
};

class CommonCompilerTest : public CommonCompilerTestBase<CommonRuntimeTest> {};

template <typename Param>
class CommonCompilerTestWithParam
    : public CommonCompilerTestBase<CommonRuntimeTestWithParam<Param>> {};

}  // namespace art

#endif  // ART_COMPILER_COMMON_COMPILER_TEST_H_
