// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef VM_STORE_BUFFER_H_
#define VM_STORE_BUFFER_H_

#include "platform/assert.h"
#include "vm/globals.h"

namespace dart {

// Forward declarations.
class Isolate;
class RawObject;

class StoreBufferBlock {
 public:
  // Each block contains kSize pointers.
  static const int32_t kSize = 1024;

  explicit StoreBufferBlock(StoreBufferBlock* next) : next_(next), top_(0) {}

  void Reset() { top_ = 0; }

  StoreBufferBlock* next() const { return next_; }

  intptr_t Count() const { return top_; }

  RawObject* At(intptr_t i) const {
    ASSERT(i >= 0);
    ASSERT(i < top_);
    return pointers_[i];
  }

  static int top_offset() { return OFFSET_OF(StoreBufferBlock, top_); }
  static int pointers_offset() {
    return OFFSET_OF(StoreBufferBlock, pointers_);
  }

 private:
  StoreBufferBlock* next_;
  int32_t top_;
  RawObject* pointers_[kSize];

  friend class StoreBuffer;

  DISALLOW_COPY_AND_ASSIGN(StoreBufferBlock);
};


class StoreBuffer {
 public:
  StoreBuffer() : blocks_(new StoreBufferBlock(NULL)), full_count_(0) {}
  ~StoreBuffer();

  intptr_t Count() const {
    return blocks_->Count() + (full_count_ * StoreBufferBlock::kSize);
  }

  void Reset();

  void AddObject(RawObject* obj) {
    StoreBufferBlock* block = blocks_;
    ASSERT(block->top_ < StoreBufferBlock::kSize);
    block->pointers_[block->top_++] = obj;
    if (block->top_ == StoreBufferBlock::kSize) {
      Expand(true);
    }
  }

  void AddObjectGC(RawObject* obj) {
    StoreBufferBlock* block = blocks_;
    ASSERT(block->top_ < StoreBufferBlock::kSize);
    block->pointers_[block->top_++] = obj;
    if (block->top_ == StoreBufferBlock::kSize) {
      Expand(false);
    }
  }

  StoreBufferBlock* Blocks() {
    StoreBufferBlock* result = blocks_;
    blocks_ = new StoreBufferBlock(NULL);
    full_count_ = 0;
    return result;
  }

  // Expand the storage and optionally check whethe to schedule an interrupt.
  void Expand(bool check);

  bool Contains(RawObject* raw);

  static int blocks_offset() { return OFFSET_OF(StoreBuffer, blocks_); }

 private:
  // Check if we run over the max number of deduplication sets.
  // If we did schedule an interrupt.
  void CheckThreshold();

  StoreBufferBlock* blocks_;
  intptr_t full_count_;

  DISALLOW_COPY_AND_ASSIGN(StoreBuffer);
};

}  // namespace dart

#endif  // VM_STORE_BUFFER_H_
