/*
 * 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.
 */

#ifndef ART_DEX2OAT_DEX_DEX_TO_DEX_COMPILER_H_
#define ART_DEX2OAT_DEX_DEX_TO_DEX_COMPILER_H_

#include <set>
#include <unordered_map>
#include <unordered_set>

#include "base/bit_vector.h"
#include "base/mutex.h"
#include "dex/invoke_type.h"
#include "dex/method_reference.h"
#include "handle.h"
#include "quicken_info.h"

namespace art {

class CompiledMethod;
class CompilerDriver;
class DexCompilationUnit;
class DexFile;

namespace dex {
struct CodeItem;
}  // namespace dex

namespace mirror {
class ClassLoader;
}  // namespace mirror

namespace optimizer {

class DexToDexCompiler {
 public:
  enum class CompilationLevel {
    kDontDexToDexCompile,   // Only meaning wrt image time interpretation.
    kOptimize               // Perform peep-hole optimizations.
  };

  explicit DexToDexCompiler(CompilerDriver* driver);

  CompiledMethod* CompileMethod(const dex::CodeItem* code_item,
                                uint32_t access_flags,
                                InvokeType invoke_type,
                                uint16_t class_def_idx,
                                uint32_t method_idx,
                                Handle<mirror::ClassLoader> class_loader,
                                const DexFile& dex_file,
                                const CompilationLevel compilation_level) WARN_UNUSED;

  void MarkForCompilation(Thread* self,
                          const MethodReference& method_ref);

  void ClearState();

  // Unquicken all methods that have conflicting quicken info. This is not done during the
  // quickening process to avoid race conditions.
  void UnquickenConflictingMethods();

  CompilerDriver* GetDriver() {
    return driver_;
  }

  bool ShouldCompileMethod(const MethodReference& ref);

  // Return the number of code items to quicken.
  size_t NumCodeItemsToQuicken(Thread* self) const;

  void SetDexFiles(const std::vector<const DexFile*>& dex_files);

 private:
  // Holds the state for compiling a single method.
  struct CompilationState;

  // Quicken state for a code item, may be referenced by multiple methods.
  struct QuickenState {
    std::vector<MethodReference> methods_;
    std::vector<uint8_t> quicken_data_;
    bool optimized_return_void_ = false;
    bool conflict_ = false;
  };

  BitVector* GetOrAddBitVectorForDex(const DexFile* dex_file) REQUIRES(lock_);

  CompilerDriver* const driver_;

  // State for adding methods (should this be in its own class?).
  const DexFile* active_dex_file_ = nullptr;
  BitVector* active_bit_vector_ = nullptr;

  // Lock that guards duplicate code items and the bitmap.
  mutable Mutex lock_;
  // Record what method references are going to get quickened.
  std::unordered_map<const DexFile*, BitVector> should_quicken_;
  // Guarded by lock_ during writing, accessed without a lock during quickening.
  // This is safe because no thread is adding to the shared code items during the quickening phase.
  std::unordered_set<const dex::CodeItem*> shared_code_items_;
  // Blacklisted code items are unquickened in UnquickenConflictingMethods.
  std::unordered_map<const dex::CodeItem*, QuickenState> shared_code_item_quicken_info_
      GUARDED_BY(lock_);
  // Number of added code items.
  size_t num_code_items_ GUARDED_BY(lock_) = 0u;
};

std::ostream& operator<<(std::ostream& os, const DexToDexCompiler::CompilationLevel& rhs);

}  // namespace optimizer

}  // namespace art

#endif  // ART_DEX2OAT_DEX_DEX_TO_DEX_COMPILER_H_
