/*
 * 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_STICKY_MARK_SWEEP_H_
#define ART_SRC_STICKY_MARK_SWEEP_H_

#include "base/macros.h"
#include "locks.h"
#include "partial_mark_sweep.h"
#include "utils.h"

namespace art {

class Barrier;
class CheckObjectVisitor;
class Class;
class Heap;
class MarkIfReachesAllocspaceVisitor;
class ModUnionClearCardVisitor;
class ModUnionVisitor;
class ModUnionTableBitmap;
class Object;
class TimingLogger;
class MarkStackChunk;

class StickyMarkSweep : public PartialMarkSweep {
 public:
  virtual GcType GetGcType() const {
    return kGcTypeSticky;
  }

  explicit StickyMarkSweep(Heap* heap, bool is_concurrent);
  ~StickyMarkSweep();
protected:
  virtual void BindBitmaps()
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  virtual void MarkReachableObjects()
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
      EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);

  virtual void Sweep(TimingLogger& timings, bool swap_bitmaps)
      EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);

  DISALLOW_COPY_AND_ASSIGN(StickyMarkSweep);
};

}  // namespace art

#endif  // ART_SRC_STICKY_MARK_SWEEP_H_
