};
+class V8_EXPORT HeapObjectStatistics {
+ public:
+ HeapObjectStatistics();
+ const char* object_type() { return object_type_; }
+ const char* object_sub_type() { return object_sub_type_; }
+ size_t object_count() { return object_count_; }
+ size_t object_size() { return object_size_; }
+
+ private:
+ const char* object_type_;
+ const char* object_sub_type_;
+ size_t object_count_;
+ size_t object_size_;
+
+ friend class Isolate;
+};
+
+
class RetainedObjectInfo;
bool GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
size_t index);
+ /**
+ * Returns the number of types of objects tracked in the heap at GC.
+ */
+ size_t NumberOfTrackedHeapObjectTypes();
+
+ /**
+ * Get statistics about objects in the heap.
+ *
+ * \param object_statistics The HeapObjectStatistics object to fill in
+ * statistics of objects of given type, which were live in the previous GC.
+ * \param type_index The index of the type of object to fill details about,
+ * which ranges from 0 to NumberOfTrackedHeapObjectTypes() - 1.
+ * \returns true on success.
+ */
+ bool GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics* object_statistics,
+ size_t type_index);
+
/**
* Get a call stack sample from the isolate.
* \param state Execution state.
physical_space_size_(0) { }
+HeapObjectStatistics::HeapObjectStatistics()
+ : object_type_(nullptr),
+ object_sub_type_(nullptr),
+ object_count_(0),
+ object_size_(0) {}
+
bool v8::V8::InitializeICU(const char* icu_data_file) {
return i::InitializeICU(icu_data_file);
}
}
+size_t Isolate::NumberOfTrackedHeapObjectTypes() {
+ return i::Heap::OBJECT_STATS_COUNT;
+}
+
+
+bool Isolate::GetHeapObjectStatisticsAtLastGC(
+ HeapObjectStatistics* object_statistics, size_t type_index) {
+ if (!object_statistics) return false;
+ if (type_index >= i::Heap::OBJECT_STATS_COUNT) return false;
+ if (!i::FLAG_track_gc_object_stats) return false;
+
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ i::Heap* heap = isolate->heap();
+ const char* object_type;
+ const char* object_sub_type;
+ size_t object_count = heap->object_count_last_gc(type_index);
+ size_t object_size = heap->object_size_last_gc(type_index);
+ if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
+ // There should be no objects counted when the type is unknown.
+ DCHECK_EQ(object_count, 0);
+ DCHECK_EQ(object_size, 0);
+ return false;
+ }
+
+ object_statistics->object_type_ = object_type;
+ object_statistics->object_sub_type_ = object_sub_type;
+ object_statistics->object_count_ = object_count;
+ object_statistics->object_size_ = object_size;
+ return true;
+}
+
+
void Isolate::GetStackSample(const RegisterState& state, void** frames,
size_t frames_limit, SampleInfo* sample_info) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
list = next;
}
}
+
+
+bool Heap::GetObjectTypeName(size_t index, const char** object_type,
+ const char** object_sub_type) {
+ if (index >= OBJECT_STATS_COUNT) return false;
+
+ switch (static_cast<int>(index)) {
+#define COMPARE_AND_RETURN_NAME(name) \
+ case name: \
+ *object_type = #name; \
+ *object_sub_type = ""; \
+ return true;
+ INSTANCE_TYPE_LIST(COMPARE_AND_RETURN_NAME)
+#undef COMPARE_AND_RETURN_NAME
+#define COMPARE_AND_RETURN_NAME(name) \
+ case FIRST_CODE_KIND_SUB_TYPE + Code::name: \
+ *object_type = "CODE_TYPE"; \
+ *object_sub_type = "CODE_KIND/" #name; \
+ return true;
+ CODE_KIND_LIST(COMPARE_AND_RETURN_NAME)
+#undef COMPARE_AND_RETURN_NAME
+#define COMPARE_AND_RETURN_NAME(name) \
+ case FIRST_FIXED_ARRAY_SUB_TYPE + name: \
+ *object_type = "FIXED_ARRAY_TYPE"; \
+ *object_sub_type = #name; \
+ return true;
+ FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COMPARE_AND_RETURN_NAME)
+#undef COMPARE_AND_RETURN_NAME
+#define COMPARE_AND_RETURN_NAME(name) \
+ case FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge: \
+ *object_type = "CODE_TYPE"; \
+ *object_sub_type = "CODE_AGE/" #name; \
+ return true;
+ CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME)
+#undef COMPARE_AND_RETURN_NAME
+ }
+ return false;
+}
}
} // namespace v8::internal
// Print short heap statistics.
void PrintShortHeapStatistics();
+ size_t object_count_last_gc(size_t index) {
+ return index < OBJECT_STATS_COUNT ? object_counts_last_time_[index] : 0;
+ }
+ size_t object_size_last_gc(size_t index) {
+ return index < OBJECT_STATS_COUNT ? object_sizes_last_time_[index] : 0;
+ }
+
// Write barrier support for address[offset] = o.
INLINE(void RecordWrite(Address address, int offset));
void TraceObjectStats();
void TraceObjectStat(const char* name, int count, int size, double time);
void CheckpointObjectStats();
+ bool GetObjectTypeName(size_t index, const char** object_type,
+ const char** object_sub_type);
void RegisterStrongRoots(Object** start, Object** end);
void UnregisterStrongRoots(Object** start);