// 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 intptr_t top_offset() { return OFFSET_OF(StoreBufferBlock, top_); }
  static intptr_t 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_
