// 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 "vm/flags.h"
#include "vm/freelist.h"
#include "vm/heap.h"
#include "vm/object.h"
#include "vm/raw_object.h"
#include "vm/visitor.h"

namespace dart {

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

ClassTable::ClassTable()
    : top_(kNumPredefinedCids), capacity_(0), table_(NULL),
      class_heap_stats_table_(NULL),
      predefined_class_heap_stats_table_(NULL) {
  if (Dart::vm_isolate() == NULL) {
    capacity_ = initial_capacity_;
    table_ = reinterpret_cast<RawClass**>(
        calloc(capacity_, sizeof(RawClass*)));  // NOLINT
  } else {
    // Duplicate the class table from the VM isolate.
    ClassTable* vm_class_table = Dart::vm_isolate()->class_table();
    capacity_ = vm_class_table->capacity_;
    table_ = reinterpret_cast<RawClass**>(
        calloc(capacity_, sizeof(RawClass*)));  // NOLINT
    for (intptr_t i = kObjectCid; i < kInstanceCid; i++) {
      table_[i] = vm_class_table->At(i);
    }
    table_[kFreeListElement] = vm_class_table->At(kFreeListElement);
    table_[kDynamicCid] = vm_class_table->At(kDynamicCid);
    table_[kVoidCid] = vm_class_table->At(kVoidCid);
    class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>(
        calloc(capacity_, sizeof(ClassHeapStats)));  // NOLINT
    for (intptr_t i = 0; i < capacity_; i++) {
      class_heap_stats_table_[i].Initialize();
    }
  }
  predefined_class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>(
        calloc(kNumPredefinedCids, sizeof(ClassHeapStats)));  // NOLINT
  for (intptr_t i = 0; i < kNumPredefinedCids; i++) {
    predefined_class_heap_stats_table_[i].Initialize();
  }
}


ClassTable::~ClassTable() {
  free(table_);
  free(predefined_class_heap_stats_table_);
  free(class_heap_stats_table_);
}


void ClassTable::Register(const Class& cls) {
  intptr_t index = cls.id();
  if (index != kIllegalCid) {
    ASSERT(index > 0);
    ASSERT(index < kNumPredefinedCids);
    ASSERT(table_[index] == 0);
    ASSERT(index < capacity_);
    table_[index] = cls.raw();
    // Add the vtable for this predefined class into the static vtable registry
    // if it has not been setup yet.
    cpp_vtable cls_vtable = cls.handle_vtable();
    cpp_vtable table_entry = Object::builtin_vtables_[index];
    ASSERT((table_entry == 0) || (table_entry == cls_vtable));
    if (table_entry == 0) {
      Object::builtin_vtables_[index] = cls_vtable;
    }
  } else {
    if (top_ == capacity_) {
      // Grow the capacity of the class table.
      intptr_t new_capacity = capacity_ + capacity_increment_;
      RawClass** new_table = reinterpret_cast<RawClass**>(
          realloc(table_, new_capacity * sizeof(RawClass*)));  // NOLINT
      ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>(
          realloc(class_heap_stats_table_,
                  new_capacity * sizeof(ClassHeapStats)));  // NOLINT
      for (intptr_t i = capacity_; i < new_capacity; i++) {
        new_table[i] = NULL;
        new_stats_table[i].Initialize();
      }
      capacity_ = new_capacity;
      table_ = new_table;
      class_heap_stats_table_ = new_stats_table;
    }
    ASSERT(top_ < capacity_);
    if (!Class::is_valid_id(top_)) {
      FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n",
             top_);
    }
    cls.set_id(top_);
    table_[top_] = cls.raw();
    top_++;  // Increment next index.
  }
}


void ClassTable::RegisterAt(intptr_t index, const Class& cls) {
  ASSERT(index != kIllegalCid);
  ASSERT(index >= kNumPredefinedCids);
  if (index >= capacity_) {
    // Grow the capacity of the class table.
    intptr_t new_capacity = index + capacity_increment_;
    if (!Class::is_valid_id(index) || new_capacity < capacity_) {
      FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n",
             index);
    }
    RawClass** new_table = reinterpret_cast<RawClass**>(
        realloc(table_, new_capacity * sizeof(RawClass*)));  // NOLINT
    ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>(
        realloc(class_heap_stats_table_,
                new_capacity * sizeof(ClassHeapStats)));  // NOLINT
    for (intptr_t i = capacity_; i < new_capacity; i++) {
      new_table[i] = NULL;
      new_stats_table[i].Initialize();
    }
    capacity_ = new_capacity;
    table_ = new_table;
    class_heap_stats_table_ = new_stats_table;
    ASSERT(capacity_increment_ >= 1);
  }
  ASSERT(table_[index] == 0);
  cls.set_id(index);
  table_[index] = cls.raw();
  if (index >= top_) {
    top_ = index + 1;
  }
}


void ClassTable::VisitObjectPointers(ObjectPointerVisitor* visitor) {
  ASSERT(visitor != NULL);
  visitor->VisitPointers(reinterpret_cast<RawObject**>(&table_[0]), top_);
}


void ClassTable::Validate() {
  Class& cls = Class::Handle();
  for (intptr_t i = kNumPredefinedCids; i < top_; i++) {
    // 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(i)) {
      cls = At(i);
      ASSERT(cls.IsClass());
    }
  }
}


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

  for (intptr_t i = 1; i < top_; i++) {
    cls = At(i);
    if (cls.raw() != reinterpret_cast<RawClass*>(0)) {
      name = cls.Name();
      OS::Print("%" Pd ": %s\n", i, name.ToCString());
    }
  }
}


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


void ClassHeapStats::Initialize() {
  pre_gc.Reset();
  post_gc.Reset();
  recent.Reset();
  accumulated.Reset();
  last_reset.Reset();
}


void ClassHeapStats::ResetAtNewGC() {
  pre_gc.new_count = post_gc.new_count + recent.new_count;
  pre_gc.new_size = post_gc.new_size + recent.new_size;
  // Accumulate allocations.
  accumulated.new_count += recent.new_count - last_reset.new_count;
  accumulated.new_size += recent.new_size - last_reset.new_size;
  last_reset.ResetNew();
  post_gc.ResetNew();
  recent.ResetNew();
}


void ClassHeapStats::ResetAtOldGC() {
  pre_gc.old_count = post_gc.old_count + recent.old_count;
  pre_gc.old_size = post_gc.old_size + recent.old_size;
  // Accumulate allocations.
  accumulated.old_count += recent.old_count - last_reset.old_count;
  accumulated.old_size += recent.old_size - last_reset.old_size;
  last_reset.ResetOld();
  post_gc.ResetOld();
  recent.ResetOld();
}


void ClassHeapStats::UpdateSize(intptr_t instance_size) {
  ASSERT(instance_size > 0);
  // For classes with fixed instance size we do not emit code to update
  // the size statistics. Update them here.
  pre_gc.old_size = pre_gc.old_count * instance_size;
  pre_gc.new_size = pre_gc.new_count * instance_size;
  post_gc.old_size = post_gc.old_count * instance_size;
  post_gc.new_size = post_gc.new_count * instance_size;
  recent.new_size = recent.new_count * instance_size;
  recent.old_size = recent.old_count * instance_size;
}


void ClassHeapStats::ResetAccumulator() {
  // Remember how much was allocated so we can subtract this from the result
  // when printing.
  last_reset.new_count = recent.new_count;
  last_reset.new_size = recent.new_size;
  last_reset.old_count = recent.old_count;
  last_reset.old_size = recent.old_size;
  accumulated.Reset();
}


void ClassHeapStats::PrintTOJSONArray(const Class& cls, JSONArray* array) {
  JSONObject obj(array);
  obj.AddProperty("type", "ClassHeapStats");
  obj.AddPropertyF("id", "allocationprofile/%" Pd "", cls.id());
  obj.AddProperty("class", cls);
  {
    JSONArray new_stats(&obj, "new");
    new_stats.AddValue(pre_gc.new_count);
    new_stats.AddValue(pre_gc.new_size);
    new_stats.AddValue(post_gc.new_count);
    new_stats.AddValue(post_gc.new_size);
    new_stats.AddValue(recent.new_count);
    new_stats.AddValue(recent.new_size);
    new_stats.AddValue64(accumulated.new_count + recent.new_count -
                         last_reset.new_count);
    new_stats.AddValue64(accumulated.new_size + recent.new_size -
                         last_reset.new_size);
  }
  {
    JSONArray old_stats(&obj, "old");
    old_stats.AddValue(pre_gc.old_count);
    old_stats.AddValue(pre_gc.old_size);
    old_stats.AddValue(post_gc.old_count);
    old_stats.AddValue(post_gc.old_size);
    old_stats.AddValue(recent.old_count);
    old_stats.AddValue(recent.old_size);
    old_stats.AddValue64(accumulated.old_count + recent.old_count -
                         last_reset.old_count);
    old_stats.AddValue64(accumulated.old_size + recent.old_size -
                         last_reset.old_size);
  }
}


void ClassTable::UpdateAllocatedNew(intptr_t cid, intptr_t size) {
  ClassHeapStats* stats = StatsAt(cid);
  ASSERT(stats != NULL);
  ASSERT(size != 0);
  stats->recent.AddNew(size);
}


void ClassTable::UpdateAllocatedOld(intptr_t cid, intptr_t size) {
  ClassHeapStats* stats = StatsAt(cid);
  ASSERT(stats != NULL);
  ASSERT(size != 0);
  stats->recent.AddOld(size);
}


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


ClassHeapStats* ClassTable::StatsAt(intptr_t cid) {
  ASSERT(cid > 0);
  if (cid < kNumPredefinedCids) {
    return &predefined_class_heap_stats_table_[cid];
  }
  ASSERT(cid < top_);
  return &class_heap_stats_table_[cid];
}


void ClassTable::ResetCountersOld() {
  for (intptr_t i = 0; i < kNumPredefinedCids; i++) {
    predefined_class_heap_stats_table_[i].ResetAtOldGC();
  }
  for (intptr_t i = kNumPredefinedCids; i < top_; i++) {
    class_heap_stats_table_[i].ResetAtOldGC();
  }
}


void ClassTable::ResetCountersNew() {
  for (intptr_t i = 0; i < kNumPredefinedCids; i++) {
    predefined_class_heap_stats_table_[i].ResetAtNewGC();
  }
  for (intptr_t i = kNumPredefinedCids; i < top_; i++) {
    class_heap_stats_table_[i].ResetAtNewGC();
  }
}


void ClassTable::AllocationProfilePrintToJSONStream(JSONStream* stream) {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate != NULL);
  Heap* heap = isolate->heap();
  ASSERT(heap != NULL);
  JSONObject obj(stream);
  obj.AddProperty("type", "AllocationProfile");
  obj.AddProperty("id", "allocationprofile");
  {
    JSONObject heaps(&obj, "heaps");
    {
      heap->PrintToJSONObject(Heap::kNew, &heaps);
    }
    {
      heap->PrintToJSONObject(Heap::kOld, &heaps);
    }
  }
  {
    Class& cls = Class::Handle();
    JSONArray arr(&obj, "members");
    for (intptr_t i = 1; i < kNumPredefinedCids; i++) {
      if (!HasValidClassAt(i) || (i == kFreeListElement) || (i == kSmiCid)) {
        continue;
      }
      cls = At(i);
      if (!(cls.is_finalized() || cls.is_prefinalized())) {
        // Not finalized.
        continue;
      }
      if (ShouldUpdateSizeForClassId(i)) {
        intptr_t instance_size = cls.instance_size();
        predefined_class_heap_stats_table_[i].UpdateSize(instance_size);
      }
      predefined_class_heap_stats_table_[i].PrintTOJSONArray(cls, &arr);
    }
    for (intptr_t i = kNumPredefinedCids; i < top_; i++) {
      if (!HasValidClassAt(i)) {
        continue;
      }
      cls = At(i);
      if (!(cls.is_finalized() || cls.is_prefinalized())) {
        // Not finalized.
        continue;
      }
      if (ShouldUpdateSizeForClassId(i)) {
        intptr_t instance_size = cls.instance_size();
        class_heap_stats_table_[i].UpdateSize(instance_size);
      }
      class_heap_stats_table_[i].PrintTOJSONArray(cls, &arr);
    }
  }
}


void ClassTable::ResetAllocationAccumulators() {
  Class& cls = Class::Handle();
  for (intptr_t i = 1; i < kNumPredefinedCids; i++) {
    if (!HasValidClassAt(i) || (i == kFreeListElement) || (i == kSmiCid)) {
      continue;
    }
    cls = At(i);
    if (!(cls.is_finalized() || cls.is_prefinalized())) {
      // Not finalized.
      continue;
    }
    // Update size before resetting accumulator.
    if (ShouldUpdateSizeForClassId(i)) {
      intptr_t instance_size = cls.instance_size();
      predefined_class_heap_stats_table_[i].UpdateSize(instance_size);
    }
    predefined_class_heap_stats_table_[i].ResetAccumulator();
  }
  for (intptr_t i = kNumPredefinedCids; i < top_; i++) {
    if (!HasValidClassAt(i)) {
      continue;
    }
    cls = At(i);
    if (!(cls.is_finalized() || cls.is_prefinalized())) {
      // Not finalized.
      continue;
    }
    // Update size before resetting accumulator.
    if (ShouldUpdateSizeForClassId(i)) {
      intptr_t instance_size = cls.instance_size();
      class_heap_stats_table_[i].UpdateSize(instance_size);
    }
    class_heap_stats_table_[i].ResetAccumulator();
  }
}


void ClassTable::UpdateLiveOld(intptr_t cid, intptr_t size) {
  ClassHeapStats* stats = StatsAt(cid);
  ASSERT(stats != NULL);
  ASSERT(size >= 0);
  stats->post_gc.AddOld(size);
}


void ClassTable::UpdateLiveNew(intptr_t cid, intptr_t size) {
  ClassHeapStats* stats = StatsAt(cid);
  ASSERT(stats != NULL);
  ASSERT(size >= 0);
  stats->post_gc.AddNew(size);
}


}  // namespace dart
