/*
 * Copyright (C) 2012 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_SRC_GREENLAND_INFERRED_REG_CATEGORY_MAP_H_
#define ART_SRC_GREENLAND_INFERRED_REG_CATEGORY_MAP_H_

#include "backend_types.h"

#include <stdint.h>
#include <vector>

#include "safe_map.h"

namespace art {
namespace greenland {

class InferredRegCategoryMap {
 private:
  class RegCategoryLine {
   private:
    typedef SafeMap<uint16_t, uint8_t> Table;
    Table reg_category_line_;

   public:
    RegCategory GetRegCategory(uint16_t reg_idx) const {
      // TODO: C++0x auto
      Table::const_iterator result = reg_category_line_.find(reg_idx);
      if (result == reg_category_line_.end()) {
        return kRegUnknown;
      }
      return static_cast<RegCategory>(result->second);
    }

    void SetRegCategory(uint16_t reg_idx, RegCategory cat) {
      if (cat != kRegUnknown) {
        reg_category_line_.Put(reg_idx, cat);
      }
    }

    bool operator==(RegCategoryLine const& rhs) const {
      return reg_category_line_ == rhs.reg_category_line_;
    }
    bool operator!=(RegCategoryLine const& rhs) const {
      return reg_category_line_ != rhs.reg_category_line_;
    }
  };

 public:
  InferredRegCategoryMap(uint32_t insns_size_in_code_units, uint8_t regs_size);

  ~InferredRegCategoryMap();

  RegCategory GetRegCategory(uint32_t dex_pc, uint16_t reg_idx) const;
  void SetRegCategory(uint32_t dex_pc, uint16_t reg_idx, RegCategory cat);

  bool IsRegCanBeObject(uint16_t reg_idx) const;
  void SetRegCanBeObject(uint16_t reg_idx);

  bool operator==(InferredRegCategoryMap const& rhs) const;
  bool operator!=(InferredRegCategoryMap const& rhs) const;

 private:
  uint16_t registers_size_;

  std::vector<RegCategoryLine*> lines_;

  std::vector<bool> can_be_object_;

  DISALLOW_COPY_AND_ASSIGN(InferredRegCategoryMap);
};


} // namespace greenland
} // namespace art

#endif // ART_SRC_GREENLAND_INFERRED_REG_CATEGORY_MAP_H_
