Use folly::dynamic::object and folly::dynamic::string exclusivly
[hiphop-php.git] / hphp / runtime / base / profile-dump.h
bloba87f19a852dfc38b5c094372db66a39fe2bd557b
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_PROFILE_DUMP_H_
18 #define incl_HPHP_PROFILE_DUMP_H_
20 #include "hphp/runtime/vm/srckey.h"
22 #include <mutex>
23 #include <condition_variable>
25 namespace HPHP {
27 // A StackTrace is represented by SrcKeys, which uniquely identify logical
28 // source locations. The lowermost stack frame recorded should go in the
29 // lowest index of the vector.
30 typedef std::vector<SrcKey> ProfileStackTrace;
32 // pprof format requires us to keep track of the number of live objects
33 // (or total in the accumulative case), and the number of bytes they occupy.
34 struct SiteAllocations {
35 size_t m_count;
36 size_t m_bytes;
38 // operators for merging shorthand
39 SiteAllocations &operator+=(size_t bytes) {
40 m_count++;
41 m_bytes += bytes;
42 return *this;
44 SiteAllocations &operator-=(size_t bytes) {
45 m_count--;
46 m_bytes -= bytes;
47 return *this;
50 SiteAllocations &operator+=(const SiteAllocations &allocs) {
51 m_count += allocs.m_count;
52 m_bytes += allocs.m_bytes;
53 return *this;
55 SiteAllocations &operator-=(const SiteAllocations &allocs) {
56 m_count -= allocs.m_count;
57 m_bytes -= allocs.m_bytes;
58 return *this;
62 // Allocation data for each stack trace. pprof wants both what is currently
63 // being used and what was allocated across the lifetime of the heap.
64 struct ProfileDump {
65 void clear() {
66 m_currentlyAllocated.clear();
67 m_accumAllocated.clear();
68 m_numDumps = 0;
71 void addAlloc(size_t size, const ProfileStackTrace &trace) {
72 m_numDumps = 1;
73 m_currentlyAllocated[trace] += size;
74 m_accumAllocated[trace] += size;
76 void removeAlloc(size_t size, const ProfileStackTrace &trace) {
77 m_numDumps = 1;
78 auto &current = m_currentlyAllocated[trace];
79 current -= size;
80 assert(current.m_count >= 0 && current.m_bytes >= 0);
83 std::string toPProfFormat() const;
85 template<typename F>
86 void forEachAddress(F fun) const {
87 for (const auto &data : m_accumAllocated) {
88 for (const SrcKey &sk : data.first) {
89 fun(sk);
94 // merge operation: takes another dump and adds all of its data.
95 // used for global dumps that require logging from multiple VM
96 // threads
97 ProfileDump &operator+=(const ProfileDump &dump) {
98 for (const auto &pair : dump.m_currentlyAllocated) {
99 m_currentlyAllocated[pair.first] += pair.second;
101 for (const auto &pair : dump.m_accumAllocated) {
102 m_accumAllocated[pair.first] += pair.second;
104 m_numDumps++;
105 return *this;
108 bool empty() {
109 return m_numDumps == 0;
112 private:
113 std::map<ProfileStackTrace, SiteAllocations> m_currentlyAllocated;
114 std::map<ProfileStackTrace, SiteAllocations> m_accumAllocated;
116 int m_numDumps = 0;
119 enum class ProfileType {
120 Default, // use the value of RuntimeOption::HHProfAllocationProfile to
121 // determine which mode to use
122 Heap, // only record allocations that are live at the end of a request
123 Allocation // record all allocations
126 typedef std::function<void(const ProfileDump&)> DumpFunc;
128 // Static controller for requesting and fetching profile dumps. The pprof
129 // server will place requests for dumps, and the VM threads will give
130 // their dumps to the controller if they satisfy the currently-active
131 // request. The pprof server will come and fetch the profile later, and if
132 // it needs to wait for a request to finish, it will.
133 struct ProfileController {
134 // request API
135 static bool requestNext(ProfileType type);
136 static bool requestNextURL(ProfileType type, const std::string &url);
137 static bool requestGlobal(ProfileType type);
138 static void cancelRequest();
140 // give API
141 static void offerProfile(const ProfileDump &dump);
143 // process API
144 static void waitForProfile(DumpFunc df);
146 // control API
147 static bool isTracking();
148 static bool isProfiling();
149 static ProfileType profileType();
150 private:
151 static void cleanup(const std::unique_lock<std::mutex>& lock);
156 #endif // incl_HPHP_PROFILE_DUMP_H_