// 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.

#include "vm/class_table.h"

#include <limits>
#include <memory>

#include "platform/atomic.h"
#include "vm/flags.h"
#include "vm/growable_array.h"
#include "vm/heap/heap.h"
#include "vm/object.h"
#include "vm/object_graph.h"
#include "vm/raw_object.h"
#include "vm/visitor.h"

namespace dart {

DEFINE_FLAG(bool, print_class_table, false, "Print initial class table.");

SharedClassTable::SharedClassTable()
    : top_(kNumPredefinedCids),
      capacity_(0),
      old_tables_(new MallocGrowableArray<void*>()) {
  if (Dart::vm_isolate() == NULL) {
    ASSERT(kInitialCapacity >= kNumPredefinedCids);
    capacity_ = kInitialCapacity;
    // Note that [calloc] will zero-initialize the memory.
    table_.store(reinterpret_cast<RelaxedAtomic<intptr_t>*>(
        calloc(capacity_, sizeof(RelaxedAtomic<intptr_t>))));
  } else {
    // Duplicate the class table from the VM isolate.
    auto vm_shared_class_table = Dart::vm_isolate_group()->shared_class_table();
    capacity_ = vm_shared_class_table->capacity_;
    // Note that [calloc] will zero-initialize the memory.
    RelaxedAtomic<intptr_t>* table = reinterpret_cast<RelaxedAtomic<intptr_t>*>(
        calloc(capacity_, sizeof(RelaxedAtomic<intptr_t>)));
    // The following cids don't have a corresponding class object in Dart code.
    // We therefore need to initialize them eagerly.
    for (intptr_t i = kObjectCid; i < kInstanceCid; i++) {
      table[i] = vm_shared_class_table->SizeAt(i);
    }
    table[kTypeArgumentsCid] = vm_shared_class_table->SizeAt(kTypeArgumentsCid);
    table[kFreeListElement] = vm_shared_class_table->SizeAt(kFreeListElement);
    table[kForwardingCorpse] = vm_shared_class_table->SizeAt(kForwardingCorpse);
    table[kDynamicCid] = vm_shared_class_table->SizeAt(kDynamicCid);
    table[kVoidCid] = vm_shared_class_table->SizeAt(kVoidCid);
    table_.store(table);
  }
#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
  // Note that [calloc] will zero-initialize the memory.
  unboxed_fields_map_ = static_cast<UnboxedFieldBitmap*>(
      calloc(capacity_, sizeof(UnboxedFieldBitmap)));
#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
#ifndef PRODUCT
  // Note that [calloc] will zero-initialize the memory.
  trace_allocation_table_.store(
      static_cast<uint8_t*>(calloc(capacity_, sizeof(uint8_t))));
#endif  // !PRODUCT
}
SharedClassTable::~SharedClassTable() {
  if (old_tables_ != NULL) {
    FreeOldTables();
    delete old_tables_;
  }
  free(table_.load());
  free(unboxed_fields_map_);

  NOT_IN_PRODUCT(free(trace_allocation_table_.load()));
}

void ClassTable::set_table(ClassPtr* table) {
  // We don't have to stop mutators, since the old table is the prefix of the
  // new table. But we should ensure that all writes to the current table are
  // visible once the new table is visible.
  table_.store(table);
  IsolateGroup::Current()->set_cached_class_table_table(table);
}

ClassTable::ClassTable(SharedClassTable* shared_class_table)
    : top_(kNumPredefinedCids),
      capacity_(0),
      tlc_top_(0),
      tlc_capacity_(0),
      table_(nullptr),
      tlc_table_(nullptr),
      old_class_tables_(new MallocGrowableArray<ClassPtr*>()),
      shared_class_table_(shared_class_table) {
  if (Dart::vm_isolate() == NULL) {
    ASSERT(kInitialCapacity >= kNumPredefinedCids);
    capacity_ = kInitialCapacity;
    // Note that [calloc] will zero-initialize the memory.
    // Don't use set_table because caller is supposed to set up isolates
    // cached copy when constructing ClassTable. Isolate::Current might not
    // be available at this point yet.
    table_.store(static_cast<ClassPtr*>(calloc(capacity_, sizeof(ClassPtr))));
  } else {
    // Duplicate the class table from the VM isolate.
    ClassTable* vm_class_table = Dart::vm_isolate_group()->class_table();
    capacity_ = vm_class_table->capacity_;
    // Note that [calloc] will zero-initialize the memory.
    ClassPtr* table =
        static_cast<ClassPtr*>(calloc(capacity_, sizeof(ClassPtr)));
    // The following cids don't have a corresponding class object in Dart code.
    // We therefore need to initialize them eagerly.
    for (intptr_t i = kObjectCid; i < kInstanceCid; i++) {
      table[i] = vm_class_table->At(i);
    }
    table[kTypeArgumentsCid] = vm_class_table->At(kTypeArgumentsCid);
    table[kFreeListElement] = vm_class_table->At(kFreeListElement);
    table[kForwardingCorpse] = vm_class_table->At(kForwardingCorpse);
    table[kDynamicCid] = vm_class_table->At(kDynamicCid);
    table[kVoidCid] = vm_class_table->At(kVoidCid);
    // Don't use set_table because caller is supposed to set up isolates
    // cached copy when constructing ClassTable. Isolate::Current might not
    // be available at this point yet.
    table_.store(table);
  }
}

ClassTable::~ClassTable() {
  if (old_class_tables_ != nullptr) {
    FreeOldTables();
    delete old_class_tables_;
  }
  free(table_.load());
  free(tlc_table_.load());
}

void ClassTable::AddOldTable(ClassPtr* old_class_table) {
  ASSERT(Thread::Current()->IsMutatorThread());
  old_class_tables_->Add(old_class_table);
}

void ClassTable::FreeOldTables() {
  while (old_class_tables_->length() > 0) {
    free(old_class_tables_->RemoveLast());
  }
}

void SharedClassTable::AddOldTable(intptr_t* old_table) {
  ASSERT(Thread::Current()->IsMutatorThread());
  old_tables_->Add(old_table);
}

void SharedClassTable::FreeOldTables() {
  while (old_tables_->length() > 0) {
    free(old_tables_->RemoveLast());
  }
}

void ClassTable::Register(const Class& cls) {
  ASSERT(Thread::Current()->IsMutatorThread());

  const classid_t cid = cls.id();
  ASSERT(!IsTopLevelCid(cid));

  // During the transition period we would like [SharedClassTable] to operate in
  // parallel to [ClassTable].

  const intptr_t instance_size =
      cls.is_abstract() ? 0 : Class::host_instance_size(cls.ptr());

  const intptr_t expected_cid =
      shared_class_table_->Register(cid, instance_size);

  if (cid != kIllegalCid) {
    ASSERT(cid > 0 && cid < kNumPredefinedCids && cid < top_);
    ASSERT(table_.load()[cid] == nullptr);
    table_.load()[cid] = cls.ptr();
  } else {
    if (top_ == capacity_) {
      const intptr_t new_capacity = capacity_ + kCapacityIncrement;
      Grow(new_capacity);
    }
    ASSERT(top_ < capacity_);
    cls.set_id(top_);
    table_.load()[top_] = cls.ptr();
    top_++;  // Increment next index.
  }
  ASSERT(expected_cid == cls.id());
}

void ClassTable::RegisterTopLevel(const Class& cls) {
  if (top_ >= std::numeric_limits<classid_t>::max()) {
    FATAL1("Fatal error in ClassTable::RegisterTopLevel: invalid index %" Pd
           "\n",
           top_);
  }

  ASSERT(Thread::Current()->IsMutatorThread());

  const intptr_t index = cls.id();
  ASSERT(index == kIllegalCid);

  if (tlc_top_ == tlc_capacity_) {
    const intptr_t new_capacity = tlc_capacity_ + kCapacityIncrement;
    GrowTopLevel(new_capacity);
  }
  ASSERT(tlc_top_ < tlc_capacity_);
  cls.set_id(ClassTable::CidFromTopLevelIndex(tlc_top_));
  tlc_table_.load()[tlc_top_] = cls.ptr();
  tlc_top_++;  // Increment next index.
}

intptr_t SharedClassTable::Register(intptr_t index, intptr_t size) {
  if (!Class::is_valid_id(top_)) {
    FATAL1("Fatal error in SharedClassTable::Register: invalid index %" Pd "\n",
           top_);
  }

  ASSERT(Thread::Current()->IsMutatorThread());
  if (index != kIllegalCid) {
    // We are registring the size of a predefined class.
    ASSERT(index > 0 && index < kNumPredefinedCids);
    SetSizeAt(index, size);
    return index;
  } else {
    ASSERT(size == 0);
    if (top_ == capacity_) {
      const intptr_t new_capacity = capacity_ + kCapacityIncrement;
      Grow(new_capacity);
    }
    ASSERT(top_ < capacity_);
    table_.load()[top_] = size;
    return top_++;  // Increment next index.
  }
}

void ClassTable::AllocateIndex(intptr_t index) {
  if (IsTopLevelCid(index)) {
    AllocateTopLevelIndex(index);
    return;
  }

  // This is called by a snapshot reader.
  shared_class_table_->AllocateIndex(index);
  ASSERT(Class::is_valid_id(index));

  if (index >= capacity_) {
    const intptr_t new_capacity = index + kCapacityIncrement;
    Grow(new_capacity);
  }

  ASSERT(table_.load()[index] == nullptr);
  if (index >= top_) {
    top_ = index + 1;
  }

  ASSERT(top_ == shared_class_table_->top_);
  ASSERT(capacity_ == shared_class_table_->capacity_);
}

void ClassTable::AllocateTopLevelIndex(intptr_t cid) {
  ASSERT(IsTopLevelCid(cid));
  const intptr_t tlc_index = IndexFromTopLevelCid(cid);

  if (tlc_index >= tlc_capacity_) {
    const intptr_t new_capacity = tlc_index + kCapacityIncrement;
    GrowTopLevel(new_capacity);
  }

  ASSERT(tlc_table_.load()[tlc_index] == nullptr);
  if (tlc_index >= tlc_top_) {
    tlc_top_ = tlc_index + 1;
  }
}

void ClassTable::Grow(intptr_t new_capacity) {
  ASSERT(new_capacity > capacity_);

  auto old_table = table_.load();
  auto new_table = static_cast<ClassPtr*>(
      malloc(new_capacity * sizeof(ClassPtr)));  // NOLINT
  intptr_t i;
  for (i = 0; i < capacity_; i++) {
    // Don't use memmove, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_table[i] = old_table[i];
  }
  for (; i < new_capacity; i++) {
    // Don't use memset, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_table[i] = 0;
  }
  old_class_tables_->Add(old_table);
  set_table(new_table);

  capacity_ = new_capacity;
}

void ClassTable::GrowTopLevel(intptr_t new_capacity) {
  ASSERT(new_capacity > tlc_capacity_);

  auto old_table = tlc_table_.load();
  auto new_table = static_cast<ClassPtr*>(
      malloc(new_capacity * sizeof(ClassPtr)));  // NOLINT
  intptr_t i;
  for (i = 0; i < tlc_capacity_; i++) {
    // Don't use memmove, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_table[i] = old_table[i];
  }
  for (; i < new_capacity; i++) {
    // Don't use memset, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_table[i] = 0;
  }
  old_class_tables_->Add(old_table);

  tlc_table_.store(new_table);
  tlc_capacity_ = new_capacity;
}

void SharedClassTable::AllocateIndex(intptr_t index) {
  // This is called by a snapshot reader.
  ASSERT(Class::is_valid_id(index));

  if (index >= capacity_) {
    const intptr_t new_capacity = index + kCapacityIncrement;
    Grow(new_capacity);
  }

  ASSERT(table_.load()[index] == 0);
  if (index >= top_) {
    top_ = index + 1;
  }
}

void SharedClassTable::Grow(intptr_t new_capacity) {
  ASSERT(new_capacity >= capacity_);

  RelaxedAtomic<intptr_t>* old_table = table_.load();
  RelaxedAtomic<intptr_t>* new_table =
      reinterpret_cast<RelaxedAtomic<intptr_t>*>(
          malloc(new_capacity * sizeof(RelaxedAtomic<intptr_t>)));  // NOLINT

  intptr_t i;
  for (i = 0; i < capacity_; i++) {
    // Don't use memmove, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_table[i] = old_table[i];
  }
  for (; i < new_capacity; i++) {
    // Don't use memset, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_table[i] = 0;
  }

#if !defined(PRODUCT)
  auto old_trace_table = trace_allocation_table_.load();
  auto new_trace_table =
      static_cast<uint8_t*>(malloc(new_capacity * sizeof(uint8_t)));  // NOLINT
  for (i = 0; i < capacity_; i++) {
    // Don't use memmove, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_trace_table[i] = old_trace_table[i];
  }
  for (; i < new_capacity; i++) {
    // Don't use memset, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_trace_table[i] = 0;
  }
#endif

  old_tables_->Add(old_table);
  table_.store(new_table);
  NOT_IN_PRODUCT(old_tables_->Add(old_trace_table));
  NOT_IN_PRODUCT(trace_allocation_table_.store(new_trace_table));

#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
  auto old_unboxed_fields_map = unboxed_fields_map_;
  auto new_unboxed_fields_map = static_cast<UnboxedFieldBitmap*>(
      malloc(new_capacity * sizeof(UnboxedFieldBitmap)));
  for (i = 0; i < capacity_; i++) {
    // Don't use memmove, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_unboxed_fields_map[i] = old_unboxed_fields_map[i];
  }
  for (; i < new_capacity; i++) {
    // Don't use memset, which changes this from a relaxed atomic operation
    // to a non-atomic operation.
    new_unboxed_fields_map[i] = UnboxedFieldBitmap(0);
  }
  old_tables_->Add(old_unboxed_fields_map);
  unboxed_fields_map_ = new_unboxed_fields_map;
#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)

  capacity_ = new_capacity;
}

void ClassTable::Unregister(intptr_t cid) {
  ASSERT(!IsTopLevelCid(cid));
  shared_class_table_->Unregister(cid);
  table_.load()[cid] = nullptr;
}

void ClassTable::UnregisterTopLevel(intptr_t cid) {
  ASSERT(IsTopLevelCid(cid));
  const intptr_t tlc_index = IndexFromTopLevelCid(cid);
  tlc_table_.load()[tlc_index] = nullptr;
}

void SharedClassTable::Unregister(intptr_t index) {
  table_.load()[index] = 0;
#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
  unboxed_fields_map_[index].Reset();
#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
}

void ClassTable::Remap(intptr_t* old_to_new_cid) {
  ASSERT(Thread::Current()->IsAtSafepoint());
  const intptr_t num_cids = NumCids();
  std::unique_ptr<ClassPtr[]> cls_by_old_cid(new ClassPtr[num_cids]);
  auto* table = table_.load();
  memmove(cls_by_old_cid.get(), table, sizeof(ClassPtr) * num_cids);
  for (intptr_t i = 0; i < num_cids; i++) {
    table[old_to_new_cid[i]] = cls_by_old_cid[i];
  }
}

void SharedClassTable::Remap(intptr_t* old_to_new_cid) {
  ASSERT(Thread::Current()->IsAtSafepoint());
  const intptr_t num_cids = NumCids();
  std::unique_ptr<intptr_t[]> size_by_old_cid(new intptr_t[num_cids]);
  auto* table = table_.load();
  for (intptr_t i = 0; i < num_cids; i++) {
    size_by_old_cid[i] = table[i];
  }
  for (intptr_t i = 0; i < num_cids; i++) {
    table[old_to_new_cid[i]] = size_by_old_cid[i];
  }

#if defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
  std::unique_ptr<UnboxedFieldBitmap[]> unboxed_fields_by_old_cid(
      new UnboxedFieldBitmap[num_cids]);
  for (intptr_t i = 0; i < num_cids; i++) {
    unboxed_fields_by_old_cid[i] = unboxed_fields_map_[i];
  }
  for (intptr_t i = 0; i < num_cids; i++) {
    unboxed_fields_map_[old_to_new_cid[i]] = unboxed_fields_by_old_cid[i];
  }
#endif  // defined(SUPPORT_UNBOXED_INSTANCE_FIELDS)
}

void ClassTable::VisitObjectPointers(ObjectPointerVisitor* visitor) {
  ASSERT(visitor != NULL);
  visitor->set_gc_root_type("class table");
  if (top_ != 0) {
    auto* table = table_.load();
    ObjectPtr* from = reinterpret_cast<ObjectPtr*>(&table[0]);
    ObjectPtr* to = reinterpret_cast<ObjectPtr*>(&table[top_ - 1]);
    visitor->VisitPointers(from, to);
  }
  if (tlc_top_ != 0) {
    auto* tlc_table = tlc_table_.load();
    ObjectPtr* from = reinterpret_cast<ObjectPtr*>(&tlc_table[0]);
    ObjectPtr* to = reinterpret_cast<ObjectPtr*>(&tlc_table[tlc_top_ - 1]);
    visitor->VisitPointers(from, to);
  }
  visitor->clear_gc_root_type();
}

void ClassTable::CopySizesFromClassObjects() {
  ASSERT(kIllegalCid == 0);
  for (intptr_t i = 1; i < top_; i++) {
    SetAt(i, At(i));
  }
}

void ClassTable::Validate() {
  Class& cls = Class::Handle();
  for (intptr_t cid = kNumPredefinedCids; cid < top_; cid++) {
    // Some of the class table entries maybe NULL as we create some
    // top level classes but do not add them to the list of anonymous
    // classes in a library if there are no top level fields or functions.
    // Since there are no references to these top level classes they are
    // not written into a full snapshot and will not be recreated when
    // we read back the full snapshot. These class slots end up with NULL
    // entries.
    if (HasValidClassAt(cid)) {
      cls = At(cid);
      ASSERT(cls.IsClass());
#if defined(DART_PRECOMPILER)
      // Precompiler can drop classes and set their id() to kIllegalCid.
      // It still leaves them in the class table so dropped program
      // structure could still be accessed while writing debug info.
      ASSERT((cls.id() == cid) || (cls.id() == kIllegalCid));
#else
      ASSERT(cls.id() == cid);
#endif  // defined(DART_PRECOMPILER)
    }
  }
}

void ClassTable::Print() {
  Class& cls = Class::Handle();
  String& name = String::Handle();

  for (intptr_t i = 1; i < top_; i++) {
    if (!HasValidClassAt(i)) {
      continue;
    }
    cls = At(i);
    if (cls.ptr() != nullptr) {
      name = cls.Name();
      OS::PrintErr("%" Pd ": %s\n", i, name.ToCString());
    }
  }
}

void ClassTable::SetAt(intptr_t cid, ClassPtr raw_cls) {
  if (IsTopLevelCid(cid)) {
    tlc_table_.load()[IndexFromTopLevelCid(cid)] = raw_cls;
    return;
  }

  // This is called by snapshot reader and class finalizer.
  ASSERT(cid < capacity_);
  const intptr_t size =
      raw_cls == nullptr ? 0 : Class::host_instance_size(raw_cls);
  shared_class_table_->SetSizeAt(cid, size);
  table_.load()[cid] = raw_cls;
}

#ifndef PRODUCT
void ClassTable::PrintToJSONObject(JSONObject* object) {
  Class& cls = Class::Handle();
  object->AddProperty("type", "ClassList");
  {
    JSONArray members(object, "classes");
    for (intptr_t i = ClassId::kObjectCid; i < top_; i++) {
      if (HasValidClassAt(i)) {
        cls = At(i);
        members.AddValue(cls);
      }
    }
  }
}

bool SharedClassTable::ShouldUpdateSizeForClassId(intptr_t cid) {
  return !IsVariableSizeClassId(cid);
}

intptr_t SharedClassTable::ClassOffsetFor(intptr_t cid) {
  return cid * sizeof(uint8_t);  // NOLINT
}


void ClassTable::AllocationProfilePrintJSON(JSONStream* stream, bool internal) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  auto isolate_group = isolate->group();
  Heap* heap = isolate_group->heap();
  ASSERT(heap != NULL);
  JSONObject obj(stream);
  obj.AddProperty("type", "AllocationProfile");
  if (isolate_group->last_allocationprofile_accumulator_reset_timestamp() !=
      0) {
    obj.AddPropertyF(
        "dateLastAccumulatorReset", "%" Pd64 "",
        isolate_group->last_allocationprofile_accumulator_reset_timestamp());
  }
  if (isolate_group->last_allocationprofile_gc_timestamp() != 0) {
    obj.AddPropertyF("dateLastServiceGC", "%" Pd64 "",
                     isolate_group->last_allocationprofile_gc_timestamp());
  }

  if (internal) {
    JSONObject heaps(&obj, "_heaps");
    { heap->PrintToJSONObject(Heap::kNew, &heaps); }
    { heap->PrintToJSONObject(Heap::kOld, &heaps); }
  }

  {
    JSONObject memory(&obj, "memoryUsage");
    { heap->PrintMemoryUsageJSON(&memory); }
  }

  Thread* thread = Thread::Current();
  CountObjectsVisitor visitor(thread, NumCids());
  {
    HeapIterationScope iter(thread);
    iter.IterateObjects(&visitor);
    isolate->group()->VisitWeakPersistentHandles(&visitor);
  }

  {
    JSONArray arr(&obj, "members");
    Class& cls = Class::Handle();
    for (intptr_t i = 3; i < top_; i++) {
      if (!HasValidClassAt(i)) continue;

      cls = At(i);
      if (cls.IsNull()) continue;

      JSONObject obj(&arr);
      obj.AddProperty("type", "ClassHeapStats");
      obj.AddProperty("class", cls);
      intptr_t count = visitor.new_count_[i] + visitor.old_count_[i];
      intptr_t size = visitor.new_size_[i] + visitor.old_size_[i];
      obj.AddProperty64("instancesAccumulated", count);
      obj.AddProperty64("accumulatedSize", size);
      obj.AddProperty64("instancesCurrent", count);
      obj.AddProperty64("bytesCurrent", size);

      if (internal) {
        {
          JSONArray new_stats(&obj, "_new");
          new_stats.AddValue(visitor.new_count_[i]);
          new_stats.AddValue(visitor.new_size_[i]);
          new_stats.AddValue(visitor.new_external_size_[i]);
        }
        {
          JSONArray old_stats(&obj, "_old");
          old_stats.AddValue(visitor.old_count_[i]);
          old_stats.AddValue(visitor.old_size_[i]);
          old_stats.AddValue(visitor.old_external_size_[i]);
        }
      }
    }
  }
}
#endif  // !PRODUCT

}  // namespace dart
