// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/heap/object-stats.h"

#include "src/counters.h"
#include "src/heap/heap-inl.h"
#include "src/isolate.h"
#include "src/utils.h"

namespace v8 {
namespace internal {

static base::LazyMutex object_stats_mutex = LAZY_MUTEX_INITIALIZER;


void ObjectStats::ClearObjectStats(bool clear_last_time_stats) {
  memset(object_counts_, 0, sizeof(object_counts_));
  memset(object_sizes_, 0, sizeof(object_sizes_));
  if (clear_last_time_stats) {
    memset(object_counts_last_time_, 0, sizeof(object_counts_last_time_));
    memset(object_sizes_last_time_, 0, sizeof(object_sizes_last_time_));
  }
}


void ObjectStats::TraceObjectStat(const char* name, int count, int size,
                                  double time) {
  int ms_count = heap()->ms_count();
  PrintIsolate(isolate(),
               "heap:%p, time:%f, gc:%d, type:%s, count:%d, size:%d\n",
               static_cast<void*>(heap()), time, ms_count, name, count, size);
}


void ObjectStats::TraceObjectStats() {
  base::LockGuard<base::Mutex> lock_guard(object_stats_mutex.Pointer());
  int index;
  int count;
  int size;
  int total_size = 0;
  double time = isolate()->time_millis_since_init();
#define TRACE_OBJECT_COUNT(name)                     \
  count = static_cast<int>(object_counts_[name]);    \
  size = static_cast<int>(object_sizes_[name]) / KB; \
  total_size += size;                                \
  TraceObjectStat(#name, count, size, time);
  INSTANCE_TYPE_LIST(TRACE_OBJECT_COUNT)
#undef TRACE_OBJECT_COUNT
#define TRACE_OBJECT_COUNT(name)                      \
  index = FIRST_CODE_KIND_SUB_TYPE + Code::name;      \
  count = static_cast<int>(object_counts_[index]);    \
  size = static_cast<int>(object_sizes_[index]) / KB; \
  TraceObjectStat("*CODE_" #name, count, size, time);
  CODE_KIND_LIST(TRACE_OBJECT_COUNT)
#undef TRACE_OBJECT_COUNT
#define TRACE_OBJECT_COUNT(name)                      \
  index = FIRST_FIXED_ARRAY_SUB_TYPE + name;          \
  count = static_cast<int>(object_counts_[index]);    \
  size = static_cast<int>(object_sizes_[index]) / KB; \
  TraceObjectStat("*FIXED_ARRAY_" #name, count, size, time);
  FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(TRACE_OBJECT_COUNT)
#undef TRACE_OBJECT_COUNT
#define TRACE_OBJECT_COUNT(name)                                              \
  index =                                                                     \
      FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge; \
  count = static_cast<int>(object_counts_[index]);                            \
  size = static_cast<int>(object_sizes_[index]) / KB;                         \
  TraceObjectStat("*CODE_AGE_" #name, count, size, time);
  CODE_AGE_LIST_COMPLETE(TRACE_OBJECT_COUNT)
#undef TRACE_OBJECT_COUNT
}


void ObjectStats::CheckpointObjectStats() {
  base::LockGuard<base::Mutex> lock_guard(object_stats_mutex.Pointer());
  Counters* counters = isolate()->counters();
#define ADJUST_LAST_TIME_OBJECT_COUNT(name)              \
  counters->count_of_##name()->Increment(                \
      static_cast<int>(object_counts_[name]));           \
  counters->count_of_##name()->Decrement(                \
      static_cast<int>(object_counts_last_time_[name])); \
  counters->size_of_##name()->Increment(                 \
      static_cast<int>(object_sizes_[name]));            \
  counters->size_of_##name()->Decrement(                 \
      static_cast<int>(object_sizes_last_time_[name]));
  INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
#undef ADJUST_LAST_TIME_OBJECT_COUNT
  int index;
#define ADJUST_LAST_TIME_OBJECT_COUNT(name)               \
  index = FIRST_CODE_KIND_SUB_TYPE + Code::name;          \
  counters->count_of_CODE_TYPE_##name()->Increment(       \
      static_cast<int>(object_counts_[index]));           \
  counters->count_of_CODE_TYPE_##name()->Decrement(       \
      static_cast<int>(object_counts_last_time_[index])); \
  counters->size_of_CODE_TYPE_##name()->Increment(        \
      static_cast<int>(object_sizes_[index]));            \
  counters->size_of_CODE_TYPE_##name()->Decrement(        \
      static_cast<int>(object_sizes_last_time_[index]));
  CODE_KIND_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
#undef ADJUST_LAST_TIME_OBJECT_COUNT
#define ADJUST_LAST_TIME_OBJECT_COUNT(name)               \
  index = FIRST_FIXED_ARRAY_SUB_TYPE + name;              \
  counters->count_of_FIXED_ARRAY_##name()->Increment(     \
      static_cast<int>(object_counts_[index]));           \
  counters->count_of_FIXED_ARRAY_##name()->Decrement(     \
      static_cast<int>(object_counts_last_time_[index])); \
  counters->size_of_FIXED_ARRAY_##name()->Increment(      \
      static_cast<int>(object_sizes_[index]));            \
  counters->size_of_FIXED_ARRAY_##name()->Decrement(      \
      static_cast<int>(object_sizes_last_time_[index]));
  FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
#undef ADJUST_LAST_TIME_OBJECT_COUNT
#define ADJUST_LAST_TIME_OBJECT_COUNT(name)                                   \
  index =                                                                     \
      FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge; \
  counters->count_of_CODE_AGE_##name()->Increment(                            \
      static_cast<int>(object_counts_[index]));                               \
  counters->count_of_CODE_AGE_##name()->Decrement(                            \
      static_cast<int>(object_counts_last_time_[index]));                     \
  counters->size_of_CODE_AGE_##name()->Increment(                             \
      static_cast<int>(object_sizes_[index]));                                \
  counters->size_of_CODE_AGE_##name()->Decrement(                             \
      static_cast<int>(object_sizes_last_time_[index]));
  CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
#undef ADJUST_LAST_TIME_OBJECT_COUNT

  MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
  MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
  ClearObjectStats();
}


Isolate* ObjectStats::isolate() { return heap()->isolate(); }

void ObjectStatsCollector::CountFixedArray(
    FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type,
    FixedArraySubInstanceType dictionary_type) {
  Heap* heap = fixed_array->map()->GetHeap();
  if (fixed_array->map() != heap->fixed_cow_array_map() &&
      fixed_array->map() != heap->fixed_double_array_map() &&
      fixed_array != heap->empty_fixed_array()) {
    if (fixed_array->IsDictionary()) {
      heap->object_stats_->RecordFixedArraySubTypeStats(dictionary_type,
                                                        fixed_array->Size());
    } else {
      heap->object_stats_->RecordFixedArraySubTypeStats(fast_type,
                                                        fixed_array->Size());
    }
  }
}

void ObjectStatsCollector::CollectStatistics(StaticVisitorBase::VisitorId id,
                                             Map* map, HeapObject* obj) {
  // Record any type specific statistics here.
  switch (id) {
    case StaticVisitorBase::kVisitMap:
      RecordMapStats(map, obj);
      break;
    case StaticVisitorBase::kVisitCode:
      RecordCodeStats(map, obj);
      break;
    case StaticVisitorBase::kVisitSharedFunctionInfo:
      RecordSharedFunctionInfoStats(map, obj);
      break;
    case StaticVisitorBase::kVisitFixedArray:
      RecordFixedArrayStats(map, obj);
      break;
    default:
      break;
  }

  Heap* heap = map->GetHeap();
  int object_size = obj->Size();
  heap->object_stats_->RecordObjectStats(map->instance_type(), object_size);
}

void ObjectStatsCollector::CollectFixedArrayStatistics(HeapObject* obj) {
  if (obj->IsJSObject()) {
    JSObject* object = JSObject::cast(obj);
    CountFixedArray(object->elements(), DICTIONARY_ELEMENTS_SUB_TYPE,
                    FAST_ELEMENTS_SUB_TYPE);
    CountFixedArray(object->properties(), DICTIONARY_PROPERTIES_SUB_TYPE,
                    FAST_PROPERTIES_SUB_TYPE);
  }
}

void ObjectStatsCollector::RecordMapStats(Map* map, HeapObject* obj) {
  Heap* heap = map->GetHeap();
  Map* map_obj = Map::cast(obj);
  DCHECK(map->instance_type() == MAP_TYPE);
  DescriptorArray* array = map_obj->instance_descriptors();
  if (map_obj->owns_descriptors() && array != heap->empty_descriptor_array()) {
    int fixed_array_size = array->Size();
    heap->object_stats_->RecordFixedArraySubTypeStats(DESCRIPTOR_ARRAY_SUB_TYPE,
                                                      fixed_array_size);
  }
  if (map_obj->has_code_cache()) {
    FixedArray* cache = map_obj->code_cache();
    heap->object_stats_->RecordFixedArraySubTypeStats(MAP_CODE_CACHE_SUB_TYPE,
                                                      cache->Size());
  }
}

void ObjectStatsCollector::RecordCodeStats(Map* map, HeapObject* obj) {
  Heap* heap = map->GetHeap();
  int object_size = obj->Size();
  DCHECK(map->instance_type() == CODE_TYPE);
  Code* code_obj = Code::cast(obj);
  heap->object_stats_->RecordCodeSubTypeStats(code_obj->kind(),
                                              code_obj->GetAge(), object_size);
}

void ObjectStatsCollector::RecordSharedFunctionInfoStats(Map* map,
                                                         HeapObject* obj) {
  Heap* heap = map->GetHeap();
  SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
  if (sfi->scope_info() != heap->empty_fixed_array()) {
    heap->object_stats_->RecordFixedArraySubTypeStats(
        SCOPE_INFO_SUB_TYPE, FixedArray::cast(sfi->scope_info())->Size());
  }
}

void ObjectStatsCollector::RecordFixedArrayStats(Map* map, HeapObject* obj) {
  Heap* heap = map->GetHeap();
  FixedArray* fixed_array = FixedArray::cast(obj);
  if (fixed_array == heap->string_table()) {
    heap->object_stats_->RecordFixedArraySubTypeStats(STRING_TABLE_SUB_TYPE,
                                                      fixed_array->Size());
  }
}

void MarkCompactObjectStatsVisitor::Initialize(
    VisitorDispatchTable<Callback>* original) {
  // Copy the original visitor table to make call-through possible. After we
  // preserved a copy locally, we patch the original table to call us.
  table_.CopyFrom(original);
#define COUNT_FUNCTION(id) original->Register(kVisit##id, Visit<kVisit##id>);
  VISITOR_ID_LIST(COUNT_FUNCTION)
#undef COUNT_FUNCTION
}

template <MarkCompactObjectStatsVisitor::VisitorId id>
void MarkCompactObjectStatsVisitor::Visit(Map* map, HeapObject* obj) {
  ObjectStatsCollector::CollectStatistics(id, map, obj);
  table_.GetVisitorById(id)(map, obj);
  ObjectStatsCollector::CollectFixedArrayStatistics(obj);
}

void IncrementalMarkingObjectStatsVisitor::Initialize(
    VisitorDispatchTable<Callback>* original) {
  // Copy the original visitor table to make call-through possible. After we
  // preserved a copy locally, we patch the original table to call us.
  table_.CopyFrom(original);
#define COUNT_FUNCTION(id) original->Register(kVisit##id, Visit<kVisit##id>);
  VISITOR_ID_LIST(COUNT_FUNCTION)
#undef COUNT_FUNCTION
}

template <IncrementalMarkingObjectStatsVisitor::VisitorId id>
void IncrementalMarkingObjectStatsVisitor::Visit(Map* map, HeapObject* obj) {
  ObjectStatsCollector::CollectStatistics(id, map, obj);
  table_.GetVisitorById(id)(map, obj);
  ObjectStatsCollector::CollectFixedArrayStatistics(obj);
}

}  // namespace internal
}  // namespace v8
