// 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(thread).
//   Handles allocated in this manner are destroyed when the HandleScope
//   object is destroyed.
// Code that uses scoped handles typically looks as follows:
//   {
//     HANDLESCOPE(thread);
//     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(thread);
//   ....
//   ....
// }


// Forward declarations.
class ObjectPointerVisitor;
class Thread;

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

class HandleVisitor {
 public:
  explicit HandleVisitor(Thread* thread) : thread_(thread) {}
  virtual ~HandleVisitor() {}

  Thread* thread() const { return thread_; }

  virtual void VisitHandle(uword addr) = 0;

 private:
  Thread* thread_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(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(Zone* zone);

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

  // 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 Thread;
  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 of 'zone', which must be
  // the current zone. This handle is valid only in the current handle scope
  // and is destroyed when the current handle scope ends.
  static uword AllocateHandle(Zone* zone);

  // Allocates a handle in 'zone', which must be the current zone. This handle
  // will be destroyed when the current zone is destroyed.
  static uword AllocateZoneHandle(Zone* zone);

  // 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();

  friend class ApiZone;
  friend class ApiNativeScope;
};


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

 private:
  void Initialize();

  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(thread)                                                    \
    dart::HandleScope vm_internal_handles_scope_(thread);


// 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(thread);
//   ....
//   .....
//   critical code that manipulates dart objects directly.
//   ....
// }
#if defined(DEBUG)
class NoHandleScope : public StackResource {
 public:
  explicit NoHandleScope(Thread* thread);
  ~NoHandleScope();

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

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

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

}  // namespace dart

#endif  // VM_HANDLES_H_
