1 : // Copyright 2012 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 structure and functions useful to grinders that process basic-
16 : // block frequency data.
17 :
18 : #ifndef SYZYGY_GRINDER_BASIC_BLOCK_UTIL_H_
19 : #define SYZYGY_GRINDER_BASIC_BLOCK_UTIL_H_
20 :
21 : #include <map>
22 : #include <vector>
23 :
24 : #include "base/files/file_path.h"
25 : #include "syzygy/common/indexed_frequency_data.h"
26 : #include "syzygy/grinder/line_info.h"
27 : #include "syzygy/pe/pe_file.h"
28 : #include "syzygy/trace/protocol/call_trace_defs.h"
29 :
30 m : namespace grinder {
31 m : namespace basic_block_util {
32 :
33 : // Address related types.
34 m : typedef core::RelativeAddress RelativeAddress;
35 m : typedef core::AddressRange<RelativeAddress, size_t> RelativeAddressRange;
36 m : typedef std::vector<RelativeAddressRange> RelativeAddressRangeVector;
37 :
38 : // Module information.
39 m : typedef pe::ModuleInformation ModuleInformation;
40 :
41 : // Compares module information on identity properties alone.
42 m : struct ModuleIdentityComparator {
43 m : bool operator()(const ModuleInformation& lhs, const ModuleInformation& rhs);
44 m : };
45 :
46 : // Type definitions for the basic block entry count data.
47 m : typedef int32 EntryCountType;
48 m : typedef int32 BasicBlockOffset;
49 : // An entry count map maps from the relative virtual address of the first
50 : // instruction or data byte in the basic block, to its entry count.
51 m : typedef std::map<BasicBlockOffset, EntryCountType> EntryCountMap;
52 :
53 m : typedef std::map<ModuleInformation,
54 m : EntryCountMap,
55 m : ModuleIdentityComparator> ModuleEntryCountMap;
56 :
57 : // Type definitions for the indexed frequency data.
58 m : typedef std::pair<RelativeAddress, size_t> IndexedFrequencyOffset;
59 m : typedef std::map<IndexedFrequencyOffset, EntryCountType> IndexedFrequencyMap;
60 : // The information kept for each module.
61 m : struct IndexedFrequencyInformation {
62 m : uint32 num_entries;
63 m : uint32 num_columns;
64 m : common::IndexedFrequencyData::DataType data_type;
65 m : uint8 frequency_size;
66 m : IndexedFrequencyMap frequency_map;
67 m : };
68 :
69 m : bool operator==(const IndexedFrequencyInformation& lhs,
70 m : const IndexedFrequencyInformation& rhs);
71 :
72 : // An indexed frequency map maps from the relative virtual address of the first
73 : // instruction or data byte in the basic block, to its frequencies.
74 m : typedef std::map<ModuleInformation,
75 m : IndexedFrequencyInformation,
76 m : ModuleIdentityComparator> ModuleIndexedFrequencyMap;
77 :
78 : // This structure holds the information extracted from a PDB file for a
79 : // given module.
80 m : struct PdbInfo {
81 : // The path to this PDB file.
82 m : base::FilePath pdb_path;
83 :
84 : // Line and coverage information for all the source files associated with
85 : // a particular PDB.
86 m : LineInfo line_info;
87 :
88 : // Basic-block addresses for the module associated with a particular PDB.
89 : // Used to transform basic-block frequency data to line visits via line_info.
90 m : RelativeAddressRangeVector bb_ranges;
91 m : };
92 :
93 m : typedef std::map<ModuleInformation,
94 m : PdbInfo,
95 m : ModuleIdentityComparator> PdbInfoMap;
96 :
97 m : bool FindIndexedFrequencyInfo(
98 m : const pe::PEFile::Signature& signature,
99 m : const ModuleIndexedFrequencyMap& module_entry_map,
100 m : const IndexedFrequencyInformation** information);
101 :
102 : // A helper function to populate @p frequencies from a branching file for a
103 : // given module signature.
104 : // @param file the file containing branching information.
105 : // @param signature the signature of the module to retrieve.
106 : // @param frequencies receives the module branch frequencies.
107 : // @returns true on success, false otherwise.
108 m : bool LoadBranchStatisticsFromFile(const base::FilePath& file,
109 m : const pe::PEFile::Signature& signature,
110 m : IndexedFrequencyMap* frequencies);
111 :
112 : // A helper function to populate @p bb_ranges from the PDB file given by
113 : // @p pdb_path.
114 : // @returns true on success, false otherwise.
115 m : bool LoadBasicBlockRanges(const base::FilePath& pdb_path,
116 m : RelativeAddressRangeVector* bb_ranges);
117 :
118 : // Loads a new or retrieves the cached PDB info for the given module. This
119 : // also caches failures; it will not re-attempt to look up PDB information
120 : // if a previous attempt for the same module failed.
121 : // @param pdb_info_cache the cache of PDB info already seen.
122 : // @param module_info the info representing the module to find PDB info for.
123 : // @param pdb_info a pointer to the pdb info will be returned here.
124 : // @returns true on success, false otherwise.
125 m : bool LoadPdbInfo(PdbInfoMap* pdb_info_cache,
126 m : const ModuleInformation& module_info,
127 m : PdbInfo** pdb_info);
128 :
129 : // @returns true if the given @p size is a valid frequency size.
130 m : bool IsValidFrequencySize(size_t size);
131 :
132 : // @returns the frequency value contained in @p data for the basic_block given
133 : // by @p bb_id.
134 m : uint32 GetFrequency(const TraceIndexedFrequencyData* data,
135 m : size_t bb_id,
136 m : size_t column);
137 :
138 m : } // namespace basic_block_util
139 m : } // namespace grinder
140 :
141 : #endif // SYZYGY_GRINDER_BASIC_BLOCK_UTIL_H_
|