// 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 Mutex;
class RawObject;

// A set of RawObject*. Must be emptied before destruction (using Pop/Reset).
class StoreBufferBlock {
 public:
  // Each full block contains kSize pointers.
  static const int32_t kSize = 1024;

  void Reset() {
    top_ = 0;
    next_ = NULL;
  }

  StoreBufferBlock* next() const { return next_; }

  intptr_t Count() const { return top_; }
  bool IsFull() const { return Count() == kSize; }
  bool IsEmpty() const { return Count() == 0; }

  void Push(RawObject* obj) {
    ASSERT(!IsFull());
    pointers_[top_++] = obj;
  }

  RawObject* Pop() {
    ASSERT(!IsEmpty());
    return pointers_[--top_];
  }

#if defined(TESTING)
  bool Contains(RawObject* obj) const {
    for (intptr_t i = 0; i < Count(); i++) {
      if (pointers_[i] == obj) {
        return true;
      }
    }
    return false;
  }
#endif  // TESTING

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

 private:
  StoreBufferBlock() : next_(NULL), top_(0) {}
  ~StoreBufferBlock() {
    ASSERT(IsEmpty());  // Guard against unintentionally discarding pointers.
  }

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

  friend class StoreBuffer;

  DISALLOW_COPY_AND_ASSIGN(StoreBufferBlock);
};


class StoreBuffer {
 public:
  StoreBuffer();
  ~StoreBuffer();
  static void InitOnce();

  // Interrupt when crossing this threshold of non-empty blocks in the buffer.
  static const intptr_t kMaxNonEmpty = 100;

  // Adds and transfers ownership of the block to the buffer.
  void PushBlock(StoreBufferBlock* block, bool check_threshold = true);
  // Partially filled blocks can be reused, and there is an "inifite" supply
  // of empty blocks (reused or newly allocated). In any case, the caller
  // takes ownership of the returned block.
  StoreBufferBlock* PopBlock();
  StoreBufferBlock* PopEmptyBlock();

  // Pops and returns all non-empty blocks as a linked list (owned by caller).
  StoreBufferBlock* Blocks();

  // Discards the contents of this store buffer.
  void Reset();

  // Check whether non-empty blocks have exceeded kMaxNonEmpty.
  bool Overflowed();

 private:
  class List {
   public:
    List() : head_(NULL), length_(0) {}
    ~List();
    void Push(StoreBufferBlock* block);
    StoreBufferBlock* Pop();
    intptr_t length() const { return length_; }
    bool IsEmpty() const { return head_ == NULL; }
    StoreBufferBlock* PopAll();
   private:
    StoreBufferBlock* head_;
    intptr_t length_;
    DISALLOW_COPY_AND_ASSIGN(List);
  };

  // If needed, trims the the global cache of empty blocks.
  static void TrimGlobalEmpty();

  List full_;
  List partial_;
  Mutex* mutex_;

  static const intptr_t kMaxGlobalEmpty = 100;
  static List* global_empty_;
  static Mutex* global_mutex_;

  DISALLOW_COPY_AND_ASSIGN(StoreBuffer);
};

}  // namespace dart

#endif  // VM_STORE_BUFFER_H_
