1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Declares a backdrop class to be used with Heap events.
16 : #ifndef SYZYGY_BARD_BACKDROPS_HEAP_BACKDROP_H_
17 : #define SYZYGY_BARD_BACKDROPS_HEAP_BACKDROP_H_
18 :
19 : #include <windows.h>
20 :
21 : #include <map>
22 : #include <string>
23 :
24 : #include "base/bind.h"
25 : #include "base/callback.h"
26 : #include "base/synchronization/lock.h"
27 : #include "syzygy/bard/event.h"
28 : #include "syzygy/bard/trace_live_map.h"
29 :
30 : namespace bard {
31 : namespace backdrops {
32 :
33 : using base::Callback;
34 :
35 : // Backdrop class to be used with Heap management events. It stores the
36 : // existing heaps and objects, and maps them from and to their trace file
37 : // addresses. It also stores the total time taken to run all the commands
38 : // so far.
39 : // The class is thread safe for simultaneous access across multiple threads.
40 : class HeapBackdrop {
41 : public:
42 : using EventType = EventInterface::EventType;
43 :
44 : // @name Heap API callback signatures.
45 : // @{
46 : using HeapAllocCallback = Callback<LPVOID(HANDLE, DWORD, SIZE_T)>;
47 : using HeapCreateCallback = Callback<HANDLE(DWORD, SIZE_T, SIZE_T)>;
48 : using HeapDestroyCallback = Callback<BOOL(HANDLE)>;
49 : using HeapFreeCallback = Callback<BOOL(HANDLE, DWORD, LPVOID)>;
50 : using HeapReAllocCallback = Callback<LPVOID(HANDLE, DWORD, LPVOID, SIZE_T)>;
51 : using HeapSetInformationCallback =
52 : Callback<BOOL(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T BOOL)>;
53 : using HeapSizeCallback = Callback<SIZE_T(HANDLE, DWORD, LPCVOID)>;
54 : // @}
55 :
56 : // The following struct holds the statistics generated by a specific
57 : // function call: the sum of the time it takes to run and the number
58 : // of times it was called.
59 : struct Stats {
60 : uint64_t time;
61 : uint64_t calls;
62 : };
63 : using StatsMap = std::map<EventType, Stats>;
64 :
65 : HeapBackdrop();
66 :
67 : // @name TraceLiveMap accessors.
68 : // @{
69 E : TraceLiveMap<HANDLE>& heap_map() { return heap_map_; }
70 E : TraceLiveMap<LPVOID>& alloc_map() { return alloc_map_; }
71 :
72 : const TraceLiveMap<HANDLE>& heap_map() const { return heap_map_; }
73 : const TraceLiveMap<LPVOID>& alloc_map() const { return alloc_map_; }
74 : // @}
75 :
76 : // @name Heap API functions.
77 : // @{
78 : LPVOID HeapAlloc(HANDLE heap, DWORD flags, SIZE_T bytes);
79 : HANDLE HeapCreate(DWORD options, SIZE_T initial_size, SIZE_T maximum_size);
80 : BOOL HeapDestroy(HANDLE heap);
81 : BOOL HeapFree(HANDLE heap, DWORD flags, LPVOID mem);
82 : LPVOID HeapReAlloc(HANDLE heap, DWORD flags, LPVOID mem, SIZE_T bytes);
83 : BOOL HeapSetInformation(HANDLE heap,
84 : HEAP_INFORMATION_CLASS info_class,
85 : PVOID info,
86 : SIZE_T info_length);
87 : SIZE_T HeapSize(HANDLE heap, DWORD flags, LPCVOID mem);
88 : // @}
89 :
90 : // @name Heap API callback mutators.
91 : // @{
92 E : void set_heap_alloc(const HeapAllocCallback& heap_alloc) {
93 E : heap_alloc_ = heap_alloc;
94 E : }
95 E : void set_heap_create(const HeapCreateCallback& heap_create) {
96 E : heap_create_ = heap_create;
97 E : }
98 E : void set_heap_destroy(const HeapDestroyCallback& heap_destroy) {
99 E : heap_destroy_ = heap_destroy;
100 E : }
101 E : void set_heap_free(const HeapFreeCallback& heap_free) {
102 E : heap_free_ = heap_free;
103 E : }
104 E : void set_heap_realloc(const HeapReAllocCallback& heap_realloc) {
105 E : heap_realloc_ = heap_realloc;
106 E : }
107 : void set_heap_set_information(
108 E : const HeapSetInformationCallback& heap_set_information) {
109 E : heap_set_information_ = heap_set_information;
110 E : }
111 E : void set_heap_size(const HeapSizeCallback& heap_size) {
112 E : heap_size_ = heap_size;
113 E : }
114 : // @}
115 :
116 : // Update the total time taken by an event with type @p type.
117 : // @param type the type of the heap event.
118 : // @param time the time the heap call took to run, in cycles as
119 : // measured by rdtsc.
120 : void UpdateStats(EventType type, uint64_t time);
121 :
122 : // @returns the cumulative statistics.
123 E : const StatsMap& total_stats() const { return total_stats_; }
124 :
125 : // Destroys any heaps that have been created against this backdrop (and any
126 : // allocations as well) and clears the maps. Allows the same backdrop to be
127 : // used repeatedly without leaking.
128 : // heaps.
129 : // @note This will invoke the HeapDestroy callback.
130 : // @returns true on success, false otherwise.
131 : bool TearDown();
132 :
133 : // Sets the process heap.
134 : // @param proc_heap The process heap in the trace file.
135 : // @returns true on success, false otherwise.
136 : bool SetProcessHeap(void* proc_heap);
137 :
138 : // Configures an existing heap. This actually creates a new heap to be
139 : // used by the playback
140 : // @param heap The trace file heap to be added.
141 : // @returns true on success, false otherwise.
142 : bool AddExistingHeap(void* heap);
143 :
144 : // Exposed for unittesting.
145 : protected:
146 : // Pointers to heap API implementation that is being evaluated.
147 : HeapAllocCallback heap_alloc_;
148 : HeapCreateCallback heap_create_;
149 : HeapDestroyCallback heap_destroy_;
150 : HeapFreeCallback heap_free_;
151 : HeapReAllocCallback heap_realloc_;
152 : HeapSetInformationCallback heap_set_information_;
153 : HeapSizeCallback heap_size_;
154 :
155 : TraceLiveMap<HANDLE> heap_map_;
156 : TraceLiveMap<LPVOID> alloc_map_;
157 :
158 : // Tracks heaps created by AddExistingHeap.
159 : std::vector<HANDLE> existing_heaps_;
160 :
161 : StatsMap total_stats_;
162 :
163 : base::Lock lock_;
164 :
165 : private:
166 : DISALLOW_COPY_AND_ASSIGN(HeapBackdrop);
167 : };
168 :
169 : } // namespace backdrops
170 : } // namespace bard
171 :
172 : #endif // SYZYGY_BARD_BACKDROPS_HEAP_BACKDROP_H_
|