// 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 RUNTIME_VM_HANDLES_IMPL_H_
#define RUNTIME_VM_HANDLES_IMPL_H_

#include "vm/heap/heap.h"
#include "vm/thread.h"
#include "vm/visitor.h"

namespace dart {

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    VisitObjectPointers(ObjectPointerVisitor* visitor) {
  // Visit all zone handles.
  HandlesBlock* block = zone_blocks_;
  while (block != NULL) {
    block->VisitObjectPointers(visitor);
    block = block->next_block();
  }

  // Visit all scoped handles.
  VisitScopedHandles(visitor);
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    VisitScopedHandles(ObjectPointerVisitor* visitor) {
  HandlesBlock* block = &first_scoped_block_;
  do {
    block->VisitObjectPointers(visitor);
    if (block == scoped_blocks_) {
      return;
    }
    block = block->next_block();
  } while (block != NULL);
  UNREACHABLE();
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::Visit(
    HandleVisitor* visitor) {
  // Visit all zone handles.
  HandlesBlock* block = zone_blocks_;
  while (block != NULL) {
    block->Visit(visitor);
    block = block->next_block();
  }

  // Visit all scoped handles.
  block = &first_scoped_block_;
  do {
    block->Visit(visitor);
    block = block->next_block();
  } while (block != NULL);
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::Reset() {
  // Delete all the extra zone handle blocks allocated and reinit the first
  // zone block.
  if (zone_blocks_ != NULL) {
    DeleteHandleBlocks(zone_blocks_->next_block());
    zone_blocks_->ReInit();
  }

  // Delete all the extra scoped handle blocks allocated and reinit the first
  // scoped block.
  DeleteHandleBlocks(first_scoped_block_.next_block());
  first_scoped_block_.ReInit();
  scoped_blocks_ = &first_scoped_block_;
}

// Figure out the current handle scope using the current Zone and
// allocate a handle in that scope. The function assumes that a
// current handle scope exists. It asserts for this appropriately.
template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
uword Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    AllocateHandle(Zone* zone) {
#if defined(DEBUG)
  Thread* thread = Thread::Current();
  ASSERT(thread->top_handle_scope() != NULL);
  ASSERT(thread->MayAllocateHandles());
#endif  // DEBUG
  Handles* handles = zone->handles();
  ASSERT(handles != NULL);
  return handles->AllocateScopedHandle();
}

// The function assumes that 'zone' is the current zone and asserts for
// this appropriately.
template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
uword Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    AllocateZoneHandle(Zone* zone) {
#if defined(DEBUG)
  Thread* thread = Thread::Current();
  ASSERT(zone->ContainsNestedZone(thread->zone()));
  ASSERT(thread->MayAllocateHandles());
#endif  // DEBUG
  Handles* handles = zone->handles();
  ASSERT(handles != NULL);
  uword address = handles->AllocateHandleInZone();
  return address;
}

// Figure out the current zone using the current Thread and
// check if the specified handle has been allocated in this zone.
template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
bool Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    IsZoneHandle(uword handle) {
  // TODO(5411412): Accessing the current thread is a performance problem,
  // consider passing it down as a parameter.
  Thread* thread = Thread::Current();
  ASSERT(thread != NULL);
  ASSERT(thread->zone() != NULL);
  Handles* handles = thread->zone()->handles();
  ASSERT(handles != NULL);
  return handles->IsValidZoneHandle(handle);
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    DeleteAll() {
  // Delete all the zone allocated handle blocks.
  // GCTrace does not need to trace this call to DeleteHandleBlocks,
  // since the individual zone deletions will be caught
  // by instrumentation in the BaseZone destructor.
  DeleteHandleBlocks(zone_blocks_);
  zone_blocks_ = NULL;

  // Delete all the scoped handle blocks.
  scoped_blocks_ = first_scoped_block_.next_block();
  DeleteHandleBlocks(scoped_blocks_);
  first_scoped_block_.ReInit();
  scoped_blocks_ = &first_scoped_block_;
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    DeleteHandleBlocks(HandlesBlock* blocks) {
  while (blocks != NULL) {
    HandlesBlock* block = blocks;
    blocks = blocks->next_block();
    delete block;
  }
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    SetupNextScopeBlock() {
  if (FLAG_trace_handles) {
    OS::PrintErr("***   Handle Counts for (0x%" Px "):Zone = %d,Scoped = %d\n",
                 reinterpret_cast<intptr_t>(this), CountZoneHandles(),
                 CountScopedHandles());
  }
  if (scoped_blocks_->next_block() == NULL) {
    HandlesBlock* block = new HandlesBlock(NULL);
    if (block == NULL) {
      OUT_OF_MEMORY();
    }
    scoped_blocks_->set_next_block(block);
  }
  scoped_blocks_ = scoped_blocks_->next_block();
  scoped_blocks_->set_next_handle_slot(0);
#if defined(DEBUG)
  scoped_blocks_->ZapFreeHandles();
#endif
}

// Validation of the handle involves iterating through all the
// handle blocks to check if the handle is valid, please
// use this only in ASSERT code for verification purposes.
template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
bool Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    IsValidScopedHandle(uword handle) const {
  const HandlesBlock* iterator = &first_scoped_block_;
  while (iterator != NULL) {
    if (iterator->IsValidHandle(handle)) {
      return true;
    }
    iterator = iterator->next_block();
  }
  return false;
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
bool Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    IsValidZoneHandle(uword handle) const {
  const HandlesBlock* iterator = zone_blocks_;
  while (iterator != NULL) {
    if (iterator->IsValidHandle(handle)) {
      return true;
    }
    iterator = iterator->next_block();
  }
  return false;
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    SetupNextZoneBlock() {
  if (FLAG_trace_handles) {
    OS::PrintErr("***   Handle Counts for (0x%" Px "):Zone = %d,Scoped = %d\n",
                 reinterpret_cast<intptr_t>(this), CountZoneHandles(),
                 CountScopedHandles());
  }
  zone_blocks_ = new HandlesBlock(zone_blocks_);
  if (zone_blocks_ == NULL) {
    OUT_OF_MEMORY();
  }
}

#if defined(DEBUG)
template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    VerifyScopedHandleState() {
  HandlesBlock* block = &first_scoped_block_;
  const intptr_t end_index = (kHandleSizeInWords * kHandlesPerChunk);
  do {
    if (scoped_blocks_ == block && block->next_handle_slot() <= end_index) {
      return;
    }
    block = block->next_block();
  } while (block != NULL);
  ASSERT(false);
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    ZapFreeScopedHandles() {
  HandlesBlock* block = scoped_blocks_;
  while (block != NULL) {
    block->ZapFreeHandles();
    block = block->next_block();
  }
}
#endif

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
int Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    CountScopedHandles() const {
  int count = 0;
  const HandlesBlock* block = &first_scoped_block_;
  do {
    count += block->HandleCount();
    if (block == scoped_blocks_) {
      return count;
    }
    block = block->next_block();
  } while (block != NULL);
  UNREACHABLE();
  return 0;
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
int Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    CountZoneHandles() const {
  int count = 0;
  const HandlesBlock* block = zone_blocks_;
  while (block != NULL) {
    count += block->HandleCount();
    block = block->next_block();
  }
  return count;
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::HandlesBlock::
    ~HandlesBlock() {
#if defined(DEBUG)
  ReInit();
#endif
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    HandlesBlock::ReInit() {
  next_handle_slot_ = 0;
  next_block_ = NULL;
#if defined(DEBUG)
  ZapFreeHandles();
#endif
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    HandlesBlock::VisitObjectPointers(ObjectPointerVisitor* visitor) {
  ASSERT(visitor != NULL);
  for (intptr_t i = 0; i < next_handle_slot_; i += kHandleSizeInWords) {
    visitor->VisitPointer(
        reinterpret_cast<RawObject**>(&data_[i + kOffsetOfRawPtr / kWordSize]));
  }
}

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    HandlesBlock::Visit(HandleVisitor* visitor) {
  ASSERT(visitor != NULL);
  for (intptr_t i = 0; i < next_handle_slot_; i += kHandleSizeInWords) {
    visitor->VisitHandle(reinterpret_cast<uword>(&data_[i]));
  }
}

#if defined(DEBUG)
template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    HandlesBlock::ZapFreeHandles() {
  // Reinitialize the handle area to some uninitialized value.
  for (intptr_t i = next_handle_slot_;
       i < (kHandleSizeInWords * kHandlesPerChunk); i++) {
    data_[i] = kZapUninitializedWord;
  }
}
#endif

template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
int Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::
    HandlesBlock::HandleCount() const {
  return (next_handle_slot_ / kHandleSizeInWords);
}

}  // namespace dart

#endif  // RUNTIME_VM_HANDLES_IMPL_H_
