OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/object-stats.h" | 5 #include "src/heap/object-stats.h" |
6 | 6 |
7 #include "src/compilation-cache.h" | 7 #include "src/compilation-cache.h" |
8 #include "src/counters.h" | 8 #include "src/counters.h" |
9 #include "src/heap/heap-inl.h" | 9 #include "src/heap/heap-inl.h" |
10 #include "src/isolate.h" | 10 #include "src/isolate.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 V8_NOINLINE static void DumpJSONArray(std::stringstream& stream, size_t* array, | 45 V8_NOINLINE static void DumpJSONArray(std::stringstream& stream, size_t* array, |
46 const int len) { | 46 const int len) { |
47 stream << "["; | 47 stream << "["; |
48 for (int i = 0; i < len; i++) { | 48 for (int i = 0; i < len; i++) { |
49 stream << array[i]; | 49 stream << array[i]; |
50 if (i != (len - 1)) stream << ","; | 50 if (i != (len - 1)) stream << ","; |
51 } | 51 } |
52 stream << "]"; | 52 stream << "]"; |
53 } | 53 } |
54 | 54 |
| 55 void ObjectStats::PrintKeyAndId(const char* key, int gc_count) { |
| 56 PrintF("\"isolate\": \"%p\", \"id\": %d, \"key\": \"%s\", ", |
| 57 reinterpret_cast<void*>(isolate()), gc_count, key); |
| 58 } |
| 59 |
| 60 void ObjectStats::PrintInstanceTypeJSON(const char* key, int gc_count, |
| 61 const char* name, int index) { |
| 62 PrintF("{ "); |
| 63 PrintKeyAndId(key, gc_count); |
| 64 PrintF("\"type\": \"instance_type_data\", "); |
| 65 PrintF("\"instance_type\": %d, ", index); |
| 66 PrintF("\"instance_type_name\": \"%s\", ", name); |
| 67 PrintF("\"overall\": %zu, ", object_sizes_[index]); |
| 68 PrintF("\"count\": %zu, ", object_counts_[index]); |
| 69 PrintF("\"over_allocated\": %zu, ", over_allocated_[index]); |
| 70 PrintF("\"histogram\": "); |
| 71 PrintJSONArray(size_histogram_[index], kNumberOfBuckets); |
| 72 PrintF(","); |
| 73 PrintF("\"over_allocated_histogram\": "); |
| 74 PrintJSONArray(over_allocated_histogram_[index], kNumberOfBuckets); |
| 75 PrintF(" }\n"); |
| 76 } |
| 77 |
55 void ObjectStats::PrintJSON(const char* key) { | 78 void ObjectStats::PrintJSON(const char* key) { |
56 double time = isolate()->time_millis_since_init(); | 79 double time = isolate()->time_millis_since_init(); |
57 int gc_count = heap()->gc_count(); | 80 int gc_count = heap()->gc_count(); |
58 | 81 |
59 #define PRINT_KEY_AND_ID() \ | |
60 PrintF("\"isolate\": \"%p\", \"id\": %d, \"key\": \"%s\", ", \ | |
61 reinterpret_cast<void*>(isolate()), gc_count, key); | |
62 | |
63 // gc_descriptor | 82 // gc_descriptor |
64 PrintF("{ "); | 83 PrintF("{ "); |
65 PRINT_KEY_AND_ID(); | 84 PrintKeyAndId(key, gc_count); |
66 PrintF("\"type\": \"gc_descriptor\", \"time\": %f }\n", time); | 85 PrintF("\"type\": \"gc_descriptor\", \"time\": %f }\n", time); |
67 // bucket_sizes | 86 // bucket_sizes |
68 PrintF("{ "); | 87 PrintF("{ "); |
69 PRINT_KEY_AND_ID(); | 88 PrintKeyAndId(key, gc_count); |
70 PrintF("\"type\": \"bucket_sizes\", \"sizes\": [ "); | 89 PrintF("\"type\": \"bucket_sizes\", \"sizes\": [ "); |
71 for (int i = 0; i < kNumberOfBuckets; i++) { | 90 for (int i = 0; i < kNumberOfBuckets; i++) { |
72 PrintF("%d", 1 << (kFirstBucketShift + i)); | 91 PrintF("%d", 1 << (kFirstBucketShift + i)); |
73 if (i != (kNumberOfBuckets - 1)) PrintF(", "); | 92 if (i != (kNumberOfBuckets - 1)) PrintF(", "); |
74 } | 93 } |
75 PrintF(" ] }\n"); | 94 PrintF(" ] }\n"); |
76 // instance_type_data | |
77 #define PRINT_INSTANCE_TYPE_DATA(name, index) \ | |
78 PrintF("{ "); \ | |
79 PRINT_KEY_AND_ID(); \ | |
80 PrintF("\"type\": \"instance_type_data\", "); \ | |
81 PrintF("\"instance_type\": %d, ", index); \ | |
82 PrintF("\"instance_type_name\": \"%s\", ", name); \ | |
83 PrintF("\"overall\": %zu, ", object_sizes_[index]); \ | |
84 PrintF("\"count\": %zu, ", object_counts_[index]); \ | |
85 PrintF("\"over_allocated\": %zu, ", over_allocated_[index]); \ | |
86 PrintF("\"histogram\": "); \ | |
87 PrintJSONArray(size_histogram_[index], kNumberOfBuckets); \ | |
88 PrintF(","); \ | |
89 PrintF("\"over_allocated_histogram\": "); \ | |
90 PrintJSONArray(over_allocated_histogram_[index], kNumberOfBuckets); \ | |
91 PrintF(" }\n"); | |
92 | 95 |
93 #define INSTANCE_TYPE_WRAPPER(name) PRINT_INSTANCE_TYPE_DATA(#name, name) | 96 #define INSTANCE_TYPE_WRAPPER(name) \ |
94 #define CODE_KIND_WRAPPER(name) \ | 97 PrintInstanceTypeJSON(key, gc_count, #name, name); |
95 PRINT_INSTANCE_TYPE_DATA("*CODE_" #name, \ | 98 #define CODE_KIND_WRAPPER(name) \ |
96 FIRST_CODE_KIND_SUB_TYPE + Code::name) | 99 PrintInstanceTypeJSON(key, gc_count, "*CODE_" #name, \ |
97 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER(name) \ | 100 FIRST_CODE_KIND_SUB_TYPE + Code::name); |
98 PRINT_INSTANCE_TYPE_DATA("*FIXED_ARRAY_" #name, \ | 101 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER(name) \ |
99 FIRST_FIXED_ARRAY_SUB_TYPE + name) | 102 PrintInstanceTypeJSON(key, gc_count, "*FIXED_ARRAY_" #name, \ |
100 #define CODE_AGE_WRAPPER(name) \ | 103 FIRST_FIXED_ARRAY_SUB_TYPE + name); |
101 PRINT_INSTANCE_TYPE_DATA( \ | 104 #define CODE_AGE_WRAPPER(name) \ |
102 "*CODE_AGE_" #name, \ | 105 PrintInstanceTypeJSON( \ |
103 FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge) | 106 key, gc_count, "*CODE_AGE_" #name, \ |
| 107 FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge); |
104 | 108 |
105 INSTANCE_TYPE_LIST(INSTANCE_TYPE_WRAPPER) | 109 INSTANCE_TYPE_LIST(INSTANCE_TYPE_WRAPPER) |
106 CODE_KIND_LIST(CODE_KIND_WRAPPER) | 110 CODE_KIND_LIST(CODE_KIND_WRAPPER) |
107 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER) | 111 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER) |
108 CODE_AGE_LIST_COMPLETE(CODE_AGE_WRAPPER) | 112 CODE_AGE_LIST_COMPLETE(CODE_AGE_WRAPPER) |
109 | 113 |
110 #undef INSTANCE_TYPE_WRAPPER | 114 #undef INSTANCE_TYPE_WRAPPER |
111 #undef CODE_KIND_WRAPPER | 115 #undef CODE_KIND_WRAPPER |
112 #undef FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER | 116 #undef FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER |
113 #undef CODE_AGE_WRAPPER | 117 #undef CODE_AGE_WRAPPER |
114 #undef PRINT_INSTANCE_TYPE_DATA | 118 #undef PRINT_INSTANCE_TYPE_DATA |
115 #undef PRINT_KEY_AND_ID | 119 #undef PRINT_KEY_AND_ID |
116 } | 120 } |
117 | 121 |
| 122 void ObjectStats::DumpInstanceTypeData(std::stringstream& stream, |
| 123 const char* name, int index) { |
| 124 stream << "\"" << name << "\":{"; |
| 125 stream << "\"type\":" << static_cast<int>(index) << ","; |
| 126 stream << "\"overall\":" << object_sizes_[index] << ","; |
| 127 stream << "\"count\":" << object_counts_[index] << ","; |
| 128 stream << "\"over_allocated\":" << over_allocated_[index] << ","; |
| 129 stream << "\"histogram\":"; |
| 130 DumpJSONArray(stream, size_histogram_[index], kNumberOfBuckets); |
| 131 stream << ",\"over_allocated_histogram\":"; |
| 132 DumpJSONArray(stream, over_allocated_histogram_[index], kNumberOfBuckets); |
| 133 stream << "},"; |
| 134 } |
| 135 |
118 void ObjectStats::Dump(std::stringstream& stream) { | 136 void ObjectStats::Dump(std::stringstream& stream) { |
119 double time = isolate()->time_millis_since_init(); | 137 double time = isolate()->time_millis_since_init(); |
120 int gc_count = heap()->gc_count(); | 138 int gc_count = heap()->gc_count(); |
121 | 139 |
122 stream << "{"; | 140 stream << "{"; |
123 stream << "\"isolate\":\"" << reinterpret_cast<void*>(isolate()) << "\","; | 141 stream << "\"isolate\":\"" << reinterpret_cast<void*>(isolate()) << "\","; |
124 stream << "\"id\":" << gc_count << ","; | 142 stream << "\"id\":" << gc_count << ","; |
125 stream << "\"time\":" << time << ","; | 143 stream << "\"time\":" << time << ","; |
126 stream << "\"bucket_sizes\":["; | 144 stream << "\"bucket_sizes\":["; |
127 for (int i = 0; i < kNumberOfBuckets; i++) { | 145 for (int i = 0; i < kNumberOfBuckets; i++) { |
128 stream << (1 << (kFirstBucketShift + i)); | 146 stream << (1 << (kFirstBucketShift + i)); |
129 if (i != (kNumberOfBuckets - 1)) stream << ","; | 147 if (i != (kNumberOfBuckets - 1)) stream << ","; |
130 } | 148 } |
131 stream << "],"; | 149 stream << "],"; |
132 stream << "\"type_data\":{"; | 150 stream << "\"type_data\":{"; |
133 | 151 |
134 #define PRINT_INSTANCE_TYPE_DATA(name, index) \ | 152 #define INSTANCE_TYPE_WRAPPER(name) DumpInstanceTypeData(stream, #name, name); |
135 stream << "\"" << name << "\":{"; \ | 153 #define CODE_KIND_WRAPPER(name) \ |
136 stream << "\"type\":" << static_cast<int>(index) << ","; \ | 154 DumpInstanceTypeData(stream, "*CODE_" #name, \ |
137 stream << "\"overall\":" << object_sizes_[index] << ","; \ | 155 FIRST_CODE_KIND_SUB_TYPE + Code::name); |
138 stream << "\"count\":" << object_counts_[index] << ","; \ | |
139 stream << "\"over_allocated\":" << over_allocated_[index] << ","; \ | |
140 stream << "\"histogram\":"; \ | |
141 DumpJSONArray(stream, size_histogram_[index], kNumberOfBuckets); \ | |
142 stream << ",\"over_allocated_histogram\":"; \ | |
143 DumpJSONArray(stream, over_allocated_histogram_[index], kNumberOfBuckets); \ | |
144 stream << "},"; | |
145 | 156 |
146 #define INSTANCE_TYPE_WRAPPER(name) PRINT_INSTANCE_TYPE_DATA(#name, name) | 157 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER(name) \ |
147 #define CODE_KIND_WRAPPER(name) \ | 158 DumpInstanceTypeData(stream, "*FIXED_ARRAY_" #name, \ |
148 PRINT_INSTANCE_TYPE_DATA("*CODE_" #name, \ | 159 FIRST_FIXED_ARRAY_SUB_TYPE + name); |
149 FIRST_CODE_KIND_SUB_TYPE + Code::name) | 160 |
150 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER(name) \ | 161 #define CODE_AGE_WRAPPER(name) \ |
151 PRINT_INSTANCE_TYPE_DATA("*FIXED_ARRAY_" #name, \ | 162 DumpInstanceTypeData( \ |
152 FIRST_FIXED_ARRAY_SUB_TYPE + name) | 163 stream, "*CODE_AGE_" #name, \ |
153 #define CODE_AGE_WRAPPER(name) \ | 164 FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge); |
154 PRINT_INSTANCE_TYPE_DATA( \ | |
155 "*CODE_AGE_" #name, \ | |
156 FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge) | |
157 | 165 |
158 INSTANCE_TYPE_LIST(INSTANCE_TYPE_WRAPPER); | 166 INSTANCE_TYPE_LIST(INSTANCE_TYPE_WRAPPER); |
159 CODE_KIND_LIST(CODE_KIND_WRAPPER); | 167 CODE_KIND_LIST(CODE_KIND_WRAPPER); |
160 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER); | 168 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER); |
161 CODE_AGE_LIST_COMPLETE(CODE_AGE_WRAPPER); | 169 CODE_AGE_LIST_COMPLETE(CODE_AGE_WRAPPER); |
162 stream << "\"END\":{}}}"; | 170 stream << "\"END\":{}}}"; |
163 | 171 |
164 #undef INSTANCE_TYPE_WRAPPER | 172 #undef INSTANCE_TYPE_WRAPPER |
165 #undef CODE_KIND_WRAPPER | 173 #undef CODE_KIND_WRAPPER |
166 #undef FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER | 174 #undef FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 SLOW_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE); | 605 SLOW_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE); |
598 FixedArray* fast_cache = native_ctx->fast_template_instantiations_cache(); | 606 FixedArray* fast_cache = native_ctx->fast_template_instantiations_cache(); |
599 stats_->RecordFixedArraySubTypeStats( | 607 stats_->RecordFixedArraySubTypeStats( |
600 fast_cache, FAST_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE, | 608 fast_cache, FAST_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE, |
601 fast_cache->Size(), 0); | 609 fast_cache->Size(), 0); |
602 } | 610 } |
603 } | 611 } |
604 | 612 |
605 } // namespace internal | 613 } // namespace internal |
606 } // namespace v8 | 614 } // namespace v8 |
OLD | NEW |