• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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