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 the BasicBlockEntryCountGrinder class, which processes trace files
16 : // containing basic-block frequency data and outputs a summary JSON file.
17 :
18 : #ifndef SYZYGY_GRINDER_BASIC_BLOCK_ENTRY_COUNT_GRINDER_H_
19 : #define SYZYGY_GRINDER_BASIC_BLOCK_ENTRY_COUNT_GRINDER_H_
20 :
21 : #include <map>
22 : #include <vector>
23 :
24 : #include "base/values.h"
25 : #include "syzygy/grinder/basic_block_entry_count_serializer.h"
26 : #include "syzygy/grinder/basic_block_util.h"
27 : #include "syzygy/grinder/grinder.h"
28 :
29 : namespace grinder {
30 :
31 : // This class processes trace files containing basic-block frequency data,
32 : // populating an EntryCountMap with summary entry counts, and
33 : // generating a JSON output file.
34 : //
35 : // See basic_block_entry_count_serializer.h for the resulting JSON structure.
36 : //
37 : // The JSON output will be pretty printed if --pretty-print is included in the
38 : // command line passed to ParseCommandLine().
39 : class BasicBlockEntryCountGrinder : public GrinderInterface {
40 : public:
41 : BasicBlockEntryCountGrinder();
42 :
43 : // @name GrinderInterface implementation.
44 : // @{
45 : virtual bool ParseCommandLine(const CommandLine* command_line) OVERRIDE;
46 : virtual void SetParser(Parser* parser) OVERRIDE;
47 : virtual bool Grind() OVERRIDE;
48 : virtual bool OutputData(FILE* file) OVERRIDE;
49 : // @}
50 :
51 : // @name ParseEventHandler overrides.
52 : // @{
53 : // Override of the OnIndexedFrequency callback.
54 : // NOTE: This only process TraceIndexedFrequencyData records of the
55 : // appropriate type (basic-block entry counts).
56 : virtual void OnIndexedFrequency(
57 : base::Time time,
58 : DWORD process_id,
59 : DWORD thread_id,
60 : const TraceIndexedFrequencyData* data) OVERRIDE;
61 : // @}
62 :
63 : // @returns a map from ModuleInformation records to bb entry counts.
64 E : const basic_block_util::ModuleEntryCountMap& entry_count_map() const {
65 E : return entry_count_map_;
66 E : }
67 :
68 : protected:
69 : typedef basic_block_util::RelativeAddressRangeVector
70 : RelativeAddressRangeVector;
71 : typedef basic_block_util::ModuleInformation ModuleInformation;
72 : typedef basic_block_util::ModuleIdentityComparator ModuleIdentityComparator;
73 :
74 : // The data we store per encountered instrumented module.
75 : struct InstrumentedModuleInformation {
76 : // The basic block ranges allow us to resolve the ordinal basic block
77 : // IDs to relative offsets in the original image.
78 : RelativeAddressRangeVector block_ranges;
79 :
80 : // The module information for the original image is what goes into the
81 : // ModuleEntryCount map.
82 : ModuleInformation original_module;
83 : };
84 :
85 : typedef std::map<ModuleInformation,
86 : InstrumentedModuleInformation,
87 : ModuleIdentityComparator> InstrumentedModuleMap;
88 :
89 : // This method does the actual updating of the entry counts on receipt
90 : // of basic-block frequency data. It is implemented separately from the
91 : // main hook for unit-testing purposes.
92 : // @param module_info the module whose basic-block entries are being counted.
93 : // @param data the basic-block entry counts being reported. The data type of
94 : // this record is expected to be a basic-blocks entry counts.
95 : void UpdateBasicBlockEntryCount(
96 : const InstrumentedModuleInformation& module_info,
97 : const TraceIndexedFrequencyData* data);
98 :
99 : // Finds or creates a new entry for an encountered instrumented module.
100 : // @param module_info the module info for the instrumented module encountered.
101 : // @returns the initialized instrumented module on success, or NULL on failure
102 : // to locate the instrumented module or initialize the module information.
103 : const InstrumentedModuleInformation* FindOrCreateInstrumentedModule(
104 : const ModuleInformation* module_info);
105 :
106 : // Stores the summarized basic-block entry counts for each module encountered.
107 : basic_block_util::ModuleEntryCountMap entry_count_map_;
108 :
109 : // Stores the basic block ID maps for each module encountered.
110 : InstrumentedModuleMap instrumented_modules_;
111 :
112 : // Used to save the JSON output to a file. Also tracks the pretty-printing
113 : // status of this grinder.
114 : BasicBlockEntryCountSerializer serializer_;
115 :
116 : // Points to the parser that is feeding us events. Used to get module
117 : // information.
118 : Parser* parser_;
119 :
120 : // Set to true if any call to OnIndexedFrequency fails. Processing will
121 : // continue with a warning that results may be partial.
122 : bool event_handler_errored_;
123 :
124 : private:
125 : DISALLOW_COPY_AND_ASSIGN(BasicBlockEntryCountGrinder);
126 : };
127 :
128 : } // namespace grinder
129 :
130 : #endif // SYZYGY_GRINDER_BASIC_BLOCK_ENTRY_COUNT_GRINDER_H_
|