1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifdef V8_ENABLE_PRECISE_ZONE_STATS
6
7 #if defined(__clang__) || defined(__GLIBCXX__)
8 #include <cxxabi.h>
9 #endif // __GLIBCXX__
10 #include <cinttypes>
11 #include <cstdio>
12
13 #include "src/base/platform/wrappers.h"
14 #include "src/utils/utils.h"
15 #include "src/zone/type-stats.h"
16
17 namespace v8 {
18 namespace internal {
19
MergeWith(const TypeStats & other)20 void TypeStats::MergeWith(const TypeStats& other) {
21 for (auto const& item : other.map_) {
22 Add(item.first, item.second);
23 }
24 }
25
26 class Demangler {
27 public:
28 Demangler() = default;
~Demangler()29 ~Demangler() {
30 if (buffer_) base::Free(buffer_);
31 USE(buffer_len_); // In case demangling is not supported.
32 }
33
demangle(std::type_index type_id)34 const char* demangle(std::type_index type_id) {
35 #if defined(__clang__) || defined(__GLIBCXX__)
36 int status = -1;
37 char* result =
38 abi::__cxa_demangle(type_id.name(), buffer_, &buffer_len_, &status);
39 if (status == 0) {
40 // Upon success, the buffer_ may be reallocated.
41 buffer_ = result;
42 return buffer_;
43 }
44 #endif
45 return type_id.name();
46 }
47
48 private:
49 char* buffer_ = nullptr;
50 size_t buffer_len_ = 0;
51 };
52
Dump() const53 void TypeStats::Dump() const {
54 Demangler d;
55 PrintF("===== TypeStats =====\n");
56 PrintF("-------------+--------------+------------+--------+--------------\n");
57 PrintF(" alloc | dealloc | count | sizeof | name\n");
58 PrintF("-------------+--------------+------------+--------+--------------\n");
59 uint64_t total_allocation_count = 0;
60 uint64_t total_allocated_bytes = 0;
61 uint64_t total_deallocated_bytes = 0;
62 for (auto const& item : map_) {
63 const StatsEntry& entry = item.second;
64 total_allocation_count += entry.allocation_count;
65 total_allocated_bytes += entry.allocated_bytes;
66 total_deallocated_bytes += entry.deallocated_bytes;
67 PrintF("%12zu | %12zu | %10zu | %6zu | %s\n", entry.allocated_bytes,
68 entry.deallocated_bytes, entry.allocation_count, entry.instance_size,
69 d.demangle(item.first));
70 }
71 PrintF("%12" PRIu64 " | %12" PRIu64 " | %10" PRIu64
72 " | ===== TOTAL STATS =====\n",
73 total_allocated_bytes, total_deallocated_bytes,
74 total_allocation_count);
75 }
76
77 } // namespace internal
78 } // namespace v8
79
80 #endif // V8_ENABLE_PRECISE_ZONE_STATS
81