| 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 |