/*
 * 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_GC_HEAP_BITMAP_H_
#define ART_SRC_GC_HEAP_BITMAP_H_

#include "locks.h"
#include "space_bitmap.h"

namespace art {
class Heap;

class HeapBitmap {
 public:
  bool Test(const mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
    SpaceBitmap* bitmap = GetSpaceBitmap(obj);
    if (LIKELY(bitmap != NULL)) {
      return bitmap->Test(obj);
    } else {
      return large_objects_->Test(obj);
    }
  }

  void Clear(const mirror::Object* obj)
  EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
    SpaceBitmap* bitmap = GetSpaceBitmap(obj);
    if (LIKELY(bitmap != NULL)) {
      bitmap->Clear(obj);
    } else {
      large_objects_->Clear(obj);
    }
  }

  void Set(const mirror::Object* obj)
  EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
    SpaceBitmap* bitmap = GetSpaceBitmap(obj);
    if (LIKELY(bitmap != NULL)) {
      bitmap->Set(obj);
    } else {
      large_objects_->Set(obj);
    }
  }

  SpaceBitmap* GetSpaceBitmap(const mirror::Object* obj) {
    // TODO: C++0x auto
    for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); ++it) {
      if ((*it)->HasAddress(obj)) {
        return *it;
      }
    }
    return NULL;
  }

  void Walk(SpaceBitmap::Callback* callback, void* arg)
      SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);

  template <typename Visitor>
  void Visit(const Visitor& visitor)
      EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  // Find and replace a bitmap pointer, this is used by for the bitmap swapping in the GC.
  void ReplaceBitmap(SpaceBitmap* old_bitmap, SpaceBitmap* new_bitmap)
      EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);

  HeapBitmap(Heap* heap);

  inline SpaceSetMap* GetLargeObjects() const {
    return large_objects_;
  }

  void SetLargeObjects(SpaceSetMap* large_objects);

 private:

  const Heap* const heap_;

  void AddSpaceBitmap(SpaceBitmap* bitmap);

  typedef std::vector<SpaceBitmap*> Bitmaps;
  Bitmaps bitmaps_;

  // Large object sets.
  SpaceSetMap* large_objects_;

  friend class Heap;
};

}  // namespace art

#endif  // ART_SRC_GC_HEAP_BITMAP_H_
