// Copyright (c) 2011, 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_HANDLES_H_
#define VM_HANDLES_H_

#include "vm/allocation.h"
#include "vm/flags.h"
#include "vm/os.h"

namespace dart {

// Handles are used in the Dart Virtual Machine to ensure that access
// to dart objects in the virtual machine code is done in a
// Garbage Collection safe manner.
//
// The class Handles is the basic type that implements creation of handles and
// manages their life cycle (allocated either in the current zone or
// current handle scope).
// The two forms of handle allocation are:
// - allocation of handles in the current zone (Handle::AllocateZoneHandle).
//   Handles allocated in this manner are destroyed when the zone is destroyed.
// - allocation of handles in a scoped manner (Handle::AllocateHandle).
//   A new scope can be started using HANDLESCOPE(isolate).
//   Handles allocated in this manner are destroyed when the HandleScope
//   object is destroyed.
// Code that uses scoped handles typically looks as follows:
//   {
//     HANDLESCOPE(isolate);
//     const String& str = String::Handle(String::New("abc"));
//     .....
//     .....
//   }
// Code that uses zone handles typically looks as follows:
//   const String& str = String::ZoneHandle(String::New("abc"));
//   .....
//   .....
//
//   The Handle function for each object type internally uses the
//   Handles::AllocateHandle() function for creating handles. The Handle
//   function of the object type is the only way to create scoped handles
//   in the dart VM.
//   The ZoneHandle function for each object type internally uses the
//   Handles::AllocateZoneHandle() function for creating zone handles.
//   The ZoneHandle function of the object type is the only way to create
//   zone handles in the dart VM.
//
// There are some critical regions of the Dart VM were we may need to manipulate
// raw dart objects directly. We use NOHANDLESCOPE to assert that we do not
// add code that will allocate new handles during this critical area.
// {
//   NOHANDLESCOPE(isolate);
//   ....
//   ....
// }


// Forward declarations.
class ObjectPointerVisitor;

DECLARE_FLAG(bool, verify_handles);
DECLARE_DEBUG_FLAG(bool, trace_handles);

class HandleVisitor {
 public:
  virtual void VisitHandle(uword addr) = 0;

  virtual ~HandleVisitor() {
  }
};


template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
class Handles {
 public:
  Handles()
      : zone_blocks_(NULL),
        first_scoped_block_(NULL),
        scoped_blocks_(&first_scoped_block_) {
  }
  ~Handles() {
    DeleteAll();
  }

  // Visit all object pointers stored in the various handles.
  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  // Visit all the scoped handles.
  void VisitScopedHandles(ObjectPointerVisitor* visitor);

  // Visit all blocks that have been added since the last time
  // this method was called.
  // Be careful with this, since multiple users of this method could
  // interfere with eachother.
  // Currently only used by GC trace facility.
  void VisitUnvisitedScopedHandles(ObjectPointerVisitor* visitor);

  // Visit all of the various handles.
  void Visit(HandleVisitor* visitor);

  // Reset the handles so that we can reuse.
  void Reset();

  // Allocates a handle in the current handle scope. This handle is valid only
  // in the current handle scope and is destroyed when the current handle
  // scope ends.
  static uword AllocateHandle(Isolate* isolate);

  // Allocates a handle in the current zone. This handle will be destroyed
  // when the current zone is destroyed.
  static uword AllocateZoneHandle(Isolate* isolate);

  // Returns true if specified handle is a zone handle.
  static bool IsZoneHandle(uword handle);

 protected:
  // Allocates space for a scoped handle.
  uword AllocateScopedHandle() {
    if (scoped_blocks_->IsFull()) {
      SetupNextScopeBlock();
    }
    return scoped_blocks_->AllocateHandle();
  }

  // Returns a count of active handles (used for testing purposes).
  int CountScopedHandles() const;
  int CountZoneHandles() const;

  // Returns true if passed in handle is a valid zone handle.
  bool IsValidScopedHandle(uword handle) const;
  bool IsValidZoneHandle(uword handle) const;

 private:
  // Base structure for managing blocks of handles.
  // Handles are allocated in Chunks (each chunk holds kHandlesPerChunk
  // handles). The chunk is uninitialized, subsequent requests for handles
  // is allocated from the chunk until we run out space in the chunk,
  // at this point another chunk is allocated. These chunks are chained
  // together.
  class HandlesBlock {
   public:
    explicit HandlesBlock(HandlesBlock* next)
        : next_handle_slot_(0),
          next_block_(next) { }
    ~HandlesBlock();

    // Reinitializes handle block for reuse.
    void ReInit();

    // Returns true if the handle block is full.
    bool IsFull() const {
      return next_handle_slot_ >= (kHandleSizeInWords * kHandlesPerChunk);
    }

    // Returns true if passed in handle belongs to this block.
    bool IsValidHandle(uword handle) const {
      uword start = reinterpret_cast<uword>(data_);
      uword end = start + (kHandleSizeInWords * kWordSize * kHandlesPerChunk);
      return (start <= handle && handle < end);
    }

    // Allocates space for a handle in the data area.
    uword AllocateHandle() {
      ASSERT(!IsFull());
      uword handle_address = reinterpret_cast<uword>(data_ + next_handle_slot_);
      next_handle_slot_ += kHandleSizeInWords;
      return handle_address;
    }

    // Visit all object pointers in the handle block.
    void VisitObjectPointers(ObjectPointerVisitor* visitor);

    // Visit all of the handles in the handle block.
    void Visit(HandleVisitor* visitor);

#if defined(DEBUG)
    // Zaps the free handle area to an uninitialized value.
    void ZapFreeHandles();
#endif

    // Returns number of active handles in the handle block.
    int HandleCount() const;

    // Accessors.
    intptr_t next_handle_slot() const { return next_handle_slot_; }
    void set_next_handle_slot(intptr_t next_handle_slot) {
      next_handle_slot_ = next_handle_slot;
    }
    HandlesBlock* next_block() const { return next_block_; }
    void set_next_block(HandlesBlock* next) { next_block_ = next; }

   private:
    uword data_[kHandleSizeInWords * kHandlesPerChunk];  // Handles area.
    intptr_t next_handle_slot_;  // Next slot for allocation in current block.
    HandlesBlock* next_block_;  // Link to next block of handles.

    DISALLOW_COPY_AND_ASSIGN(HandlesBlock);
  };

  // Deletes all the allocated handle blocks.
  void DeleteAll();
  void DeleteHandleBlocks(HandlesBlock* blocks);

  // Sets up the next handle block (allocates a new one if needed).
  void SetupNextScopeBlock();

  // Allocates space for a zone handle.
  uword AllocateHandleInZone() {
    if (zone_blocks_ == NULL || zone_blocks_->IsFull()) {
      SetupNextZoneBlock();
    }
    return zone_blocks_->AllocateHandle();
  }

  // Allocates a new handle block and links it up.
  void SetupNextZoneBlock();

#if defined(DEBUG)
  // Verifies consistency of handle blocks after a scope is destroyed.
  void VerifyScopedHandleState();

  // Zaps the free scoped handles to an uninitialized value.
  void ZapFreeScopedHandles();
#endif

  HandlesBlock* zone_blocks_;  // List of zone handles.
  HandlesBlock first_scoped_block_;  // First block of scoped handles.
  HandlesBlock* scoped_blocks_;  // List of scoped handles.

  friend class HandleScope;
  friend class Dart;
  friend class ObjectStore;
  friend class Isolate;
  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(Handles);
};


static const int kVMHandleSizeInWords = 2;
static const int kVMHandlesPerChunk = 64;
static const int kOffsetOfRawPtr = kWordSize;
class VMHandles : public Handles<kVMHandleSizeInWords,
                                 kVMHandlesPerChunk,
                                 kOffsetOfRawPtr> {
 public:
  static const int kOffsetOfRawPtrInHandle = kOffsetOfRawPtr;

  VMHandles() : Handles<kVMHandleSizeInWords,
                        kVMHandlesPerChunk,
                        kOffsetOfRawPtr>() {
#ifdef DEBUG
    if (FLAG_trace_handles) {
      OS::PrintErr("*** Starting a new VM handle block 0x%"Px"\n",
                   reinterpret_cast<intptr_t>(this));
    }
#endif
  }
  ~VMHandles();

  // Visit all object pointers stored in the various handles.
  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  // Allocates a handle in the current handle scope. This handle is valid only
  // in the current handle scope and is destroyed when the current handle
  // scope ends.
  static uword AllocateHandle(Isolate* isolate);

  // Allocates a handle in the current zone. This handle will be destroyed
  // when the current zone is destroyed.
  static uword AllocateZoneHandle(Isolate* isolate);

  // Returns true if specified handle is a zone handle.
  static bool IsZoneHandle(uword handle);

  // Returns number of handles, these functions are used for testing purposes.
  static int ScopedHandleCount();
  static int ZoneHandleCount();
};


// The class HandleScope is used to start a new handles scope in the code.
// It is used as follows:
// {
//   HANDLESCOPE(isolate);
//   ....
//   .....
//   code that creates some scoped handles.
//   ....
// }
class HandleScope : public StackResource {
 public:
  explicit HandleScope(BaseIsolate* isolate);
  ~HandleScope();

 private:
  VMHandles::HandlesBlock* saved_handle_block_;  // Handle block at prev scope.
  uword saved_handle_slot_;  // Next available handle slot at previous scope.
#if defined(DEBUG)
  HandleScope* link_;  // Link to previous scope.
#endif
  DISALLOW_IMPLICIT_CONSTRUCTORS(HandleScope);
};

// Macro to start a new Handle scope.
#define HANDLESCOPE(isolate)                                                  \
    dart::HandleScope vm_internal_handles_scope_(isolate);


// The class NoHandleScope is used in critical regions of the virtual machine
// code where raw dart object pointers are directly manipulated.
// This class asserts that we do not add code that will allocate new handles
// during this critical area.
// It is used as follows:
// {
//   NOHANDLESCOPE(isolate);
//   ....
//   .....
//   critical code that manipulates dart objects directly.
//   ....
// }
#if defined(DEBUG)
class NoHandleScope : public StackResource {
 public:
  explicit NoHandleScope(BaseIsolate* isolate);
  NoHandleScope();
  ~NoHandleScope();

 private:
  DISALLOW_COPY_AND_ASSIGN(NoHandleScope);
};
#else  // defined(DEBUG)
class NoHandleScope : public ValueObject {
 public:
  explicit NoHandleScope(BaseIsolate* isolate) { }
  NoHandleScope() { }
  ~NoHandleScope() { }

 private:
  DISALLOW_COPY_AND_ASSIGN(NoHandleScope);
};
#endif  // defined(DEBUG)

// Macro to start a no handles scope in the code.
#define NOHANDLESCOPE(isolate)                                                 \
    dart::NoHandleScope no_vm_internal_handles_scope_(isolate);

}  // namespace dart

#endif  // VM_HANDLES_H_
