object-stats.h 6.84 KB
Newer Older
1 2 3 4 5 6 7 8
// 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.

#ifndef V8_HEAP_OBJECT_STATS_H_
#define V8_HEAP_OBJECT_STATS_H_

#include "src/objects.h"
9
#include "src/objects/code.h"
10

11 12 13 14 15 16
// These instance types do not exist for actual use but are merely introduced
// for object stats tracing. In contrast to Code and FixedArray sub types
// these types are not known to other counters outside of object stats
// tracing.
//
// Update LAST_VIRTUAL_TYPE below when changing this macro.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
#define VIRTUAL_INSTANCE_TYPE_LIST(V)            \
  CODE_KIND_LIST(V)                              \
  V(ARRAY_BOILERPLATE_DESCRIPTION_ELEMENTS_TYPE) \
  V(BOILERPLATE_ELEMENTS_TYPE)                   \
  V(BOILERPLATE_PROPERTY_ARRAY_TYPE)             \
  V(BOILERPLATE_PROPERTY_DICTIONARY_TYPE)        \
  V(BYTECODE_ARRAY_CONSTANT_POOL_TYPE)           \
  V(BYTECODE_ARRAY_HANDLER_TABLE_TYPE)           \
  V(COW_ARRAY_TYPE)                              \
  V(DEOPTIMIZATION_DATA_TYPE)                    \
  V(DEPENDENT_CODE_TYPE)                         \
  V(ELEMENTS_TYPE)                               \
  V(EMBEDDED_OBJECT_TYPE)                        \
  V(ENUM_CACHE_TYPE)                             \
  V(ENUM_INDICES_CACHE_TYPE)                     \
  V(FEEDBACK_VECTOR_ENTRY_TYPE)                  \
  V(FEEDBACK_VECTOR_HEADER_TYPE)                 \
  V(FEEDBACK_VECTOR_SLOT_CALL_TYPE)              \
  V(FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE)       \
  V(FEEDBACK_VECTOR_SLOT_ENUM_TYPE)              \
  V(FEEDBACK_VECTOR_SLOT_LOAD_TYPE)              \
  V(FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE)       \
  V(FEEDBACK_VECTOR_SLOT_OTHER_TYPE)             \
  V(FEEDBACK_VECTOR_SLOT_STORE_TYPE)             \
  V(FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE)      \
  V(FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE)         \
  V(GLOBAL_ELEMENTS_TYPE)                        \
  V(GLOBAL_PROPERTIES_TYPE)                      \
  V(JS_ARRAY_BOILERPLATE_TYPE)                   \
46
  V(JS_COLLECTION_TABLE_TYPE)                    \
47 48 49 50 51 52 53 54 55 56 57 58 59
  V(JS_OBJECT_BOILERPLATE_TYPE)                  \
  V(NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE)         \
  V(NUMBER_STRING_CACHE_TYPE)                    \
  V(OBJECT_PROPERTY_DICTIONARY_TYPE)             \
  V(OBJECT_TO_CODE_TYPE)                         \
  V(OPTIMIZED_CODE_LITERALS_TYPE)                \
  V(OTHER_CONTEXT_TYPE)                          \
  V(PROTOTYPE_USERS_TYPE)                        \
  V(REGEXP_MULTIPLE_CACHE_TYPE)                  \
  V(RELOC_INFO_TYPE)                             \
  V(RETAINED_MAPS_TYPE)                          \
  V(SCRIPT_LIST_TYPE)                            \
  V(SCRIPT_SHARED_FUNCTION_INFOS_TYPE)           \
60 61 62 63
  V(SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE)        \
  V(SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE)        \
  V(SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE)    \
  V(SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE)    \
64 65 66
  V(SERIALIZED_OBJECTS_TYPE)                     \
  V(SINGLE_CHARACTER_STRING_CACHE_TYPE)          \
  V(STRING_SPLIT_CACHE_TYPE)                     \
67 68
  V(STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE)      \
  V(STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE)      \
69 70 71
  V(SOURCE_POSITION_TABLE_TYPE)                  \
  V(UNCOMPILED_JS_FUNCTION_TYPE)                 \
  V(UNCOMPILED_SHARED_FUNCTION_INFO_TYPE)        \
72
  V(WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE)
73

74 75 76
namespace v8 {
namespace internal {

77 78 79
class Heap;
class Isolate;

80 81
class ObjectStats {
 public:
82 83
  static const size_t kNoOverAllocation = 0;

84
  explicit ObjectStats(Heap* heap) : heap_(heap) { ClearObjectStats(); }
85

86 87 88 89 90
  // See description on VIRTUAL_INSTANCE_TYPE_LIST.
  enum VirtualInstanceType {
#define DEFINE_VIRTUAL_INSTANCE_TYPE(type) type,
    VIRTUAL_INSTANCE_TYPE_LIST(DEFINE_VIRTUAL_INSTANCE_TYPE)
#undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
91
        LAST_VIRTUAL_TYPE = WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE,
92 93
  };

94 95 96 97
  // ObjectStats are kept in two arrays, counts and sizes. Related stats are
  // stored in a contiguous linear buffer. Stats groups are stored one after
  // another.
  enum {
98
    FIRST_VIRTUAL_TYPE = LAST_TYPE + 1,
99
    OBJECT_STATS_COUNT = FIRST_VIRTUAL_TYPE + LAST_VIRTUAL_TYPE + 1,
100 101 102 103
  };

  void ClearObjectStats(bool clear_last_time_stats = false);

104
  void PrintJSON(const char* key);
105
  void Dump(std::stringstream& stream);
106

107
  void CheckpointObjectStats();
108
  void RecordObjectStats(InstanceType type, size_t size);
109 110
  void RecordVirtualObjectStats(VirtualInstanceType type, size_t size,
                                size_t over_allocated);
111 112 113 114 115 116 117 118 119 120 121 122 123

  size_t object_count_last_gc(size_t index) {
    return object_counts_last_time_[index];
  }

  size_t object_size_last_gc(size_t index) {
    return object_sizes_last_time_[index];
  }

  Isolate* isolate();
  Heap* heap() { return heap_; }

 private:
124 125
  static const int kFirstBucketShift = 5;  // <32
  static const int kLastBucketShift = 20;  // >=1M
126 127
  static const int kFirstBucket = 1 << kFirstBucketShift;
  static const int kLastBucket = 1 << kLastBucketShift;
128
  static const int kNumberOfBuckets = kLastBucketShift - kFirstBucketShift + 1;
129
  static const int kLastValueBucketIndex = kLastBucketShift - kFirstBucketShift;
130

131 132 133 134 135 136 137 138
  void PrintKeyAndId(const char* key, int gc_count);
  // The following functions are excluded from inline to reduce the overall
  // binary size of VB. On x64 this save around 80KB.
  V8_NOINLINE void PrintInstanceTypeJSON(const char* key, int gc_count,
                                         const char* name, int index);
  V8_NOINLINE void DumpInstanceTypeData(std::stringstream& stream,
                                        const char* name, int index);

139
  int HistogramIndexFromSize(size_t size);
140

141 142
  Heap* heap_;
  // Object counts and used memory by InstanceType.
143 144 145 146
  size_t object_counts_[OBJECT_STATS_COUNT];
  size_t object_counts_last_time_[OBJECT_STATS_COUNT];
  size_t object_sizes_[OBJECT_STATS_COUNT];
  size_t object_sizes_last_time_[OBJECT_STATS_COUNT];
147 148 149 150 151
  // Approximation of overallocated memory by InstanceType.
  size_t over_allocated_[OBJECT_STATS_COUNT];
  // Detailed histograms by InstanceType.
  size_t size_histogram_[OBJECT_STATS_COUNT][kNumberOfBuckets];
  size_t over_allocated_histogram_[OBJECT_STATS_COUNT][kNumberOfBuckets];
152 153 154 155 156 157 158

  size_t tagged_fields_count_;
  size_t embedder_fields_count_;
  size_t unboxed_double_fields_count_;
  size_t raw_fields_count_;

  friend class ObjectStatsCollectorImpl;
159 160
};

161
class ObjectStatsCollector {
162
 public:
163 164 165 166 167 168
  ObjectStatsCollector(Heap* heap, ObjectStats* live, ObjectStats* dead)
      : heap_(heap), live_(live), dead_(dead) {
    DCHECK_NOT_NULL(heap_);
    DCHECK_NOT_NULL(live_);
    DCHECK_NOT_NULL(dead_);
  }
169

170 171 172
  // Collects type information of live and dead objects. Requires mark bits to
  // be present.
  void Collect();
173

174
 private:
175 176 177
  Heap* const heap_;
  ObjectStats* const live_;
  ObjectStats* const dead_;
178 179
};

180 181 182 183
}  // namespace internal
}  // namespace v8

#endif  // V8_HEAP_OBJECT_STATS_H_