1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_
18 #define ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_
19 
20 #include <sstream>
21 #include <string>
22 
23 #include "atomic.h"
24 
25 namespace art {
26 
27 enum MethodCompilationStat {
28   kAttemptCompilation = 0,
29   kCompiledBaseline,
30   kCompiledOptimized,
31   kCompiledQuick,
32   kInlinedInvoke,
33   kInstructionSimplifications,
34   kNotCompiledBranchOutsideMethodCode,
35   kNotCompiledCannotBuildSSA,
36   kNotCompiledCantAccesType,
37   kNotCompiledClassNotVerified,
38   kNotCompiledHugeMethod,
39   kNotCompiledLargeMethodNoBranches,
40   kNotCompiledMalformedOpcode,
41   kNotCompiledNoCodegen,
42   kNotCompiledNonSequentialRegPair,
43   kNotCompiledPathological,
44   kNotCompiledSpaceFilter,
45   kNotCompiledUnhandledInstruction,
46   kNotCompiledUnresolvedField,
47   kNotCompiledUnresolvedMethod,
48   kNotCompiledUnsupportedIsa,
49   kNotCompiledVerifyAtRuntime,
50   kNotOptimizedDisabled,
51   kNotOptimizedRegisterAllocator,
52   kNotOptimizedTryCatch,
53   kRemovedCheckedCast,
54   kRemovedDeadInstruction,
55   kRemovedNullCheck,
56   kLastStat
57 };
58 
59 class OptimizingCompilerStats {
60  public:
OptimizingCompilerStats()61   OptimizingCompilerStats() {}
62 
63   void RecordStat(MethodCompilationStat stat, size_t count = 1) {
64     compile_stats_[stat] += count;
65   }
66 
Log()67   void Log() const {
68     if (compile_stats_[kAttemptCompilation] == 0) {
69       LOG(INFO) << "Did not compile any method.";
70     } else {
71       size_t unoptimized_percent =
72           compile_stats_[kCompiledBaseline] * 100 / compile_stats_[kAttemptCompilation];
73       size_t optimized_percent =
74           compile_stats_[kCompiledOptimized] * 100 / compile_stats_[kAttemptCompilation];
75       size_t quick_percent =
76           compile_stats_[kCompiledQuick] * 100 / compile_stats_[kAttemptCompilation];
77       std::ostringstream oss;
78       oss << "Attempted compilation of " << compile_stats_[kAttemptCompilation] << " methods: ";
79 
80       oss << unoptimized_percent << "% (" << compile_stats_[kCompiledBaseline] << ") unoptimized, ";
81       oss << optimized_percent << "% (" << compile_stats_[kCompiledOptimized] << ") optimized, ";
82       oss << quick_percent << "% (" << compile_stats_[kCompiledQuick] << ") quick.";
83 
84       LOG(INFO) << oss.str();
85 
86       for (int i = 0; i < kLastStat; i++) {
87         if (compile_stats_[i] != 0) {
88           LOG(INFO) << PrintMethodCompilationStat(i) << ": " << compile_stats_[i];
89         }
90       }
91     }
92   }
93 
94  private:
PrintMethodCompilationStat(int stat)95   std::string PrintMethodCompilationStat(int stat) const {
96     switch (stat) {
97       case kAttemptCompilation : return "kAttemptCompilation";
98       case kCompiledBaseline : return "kCompiledBaseline";
99       case kCompiledOptimized : return "kCompiledOptimized";
100       case kCompiledQuick : return "kCompiledQuick";
101       case kInlinedInvoke : return "kInlinedInvoke";
102       case kInstructionSimplifications: return "kInstructionSimplifications";
103       case kNotCompiledBranchOutsideMethodCode: return "kNotCompiledBranchOutsideMethodCode";
104       case kNotCompiledCannotBuildSSA : return "kNotCompiledCannotBuildSSA";
105       case kNotCompiledCantAccesType : return "kNotCompiledCantAccesType";
106       case kNotCompiledClassNotVerified : return "kNotCompiledClassNotVerified";
107       case kNotCompiledHugeMethod : return "kNotCompiledHugeMethod";
108       case kNotCompiledLargeMethodNoBranches : return "kNotCompiledLargeMethodNoBranches";
109       case kNotCompiledMalformedOpcode : return "kNotCompiledMalformedOpcode";
110       case kNotCompiledNoCodegen : return "kNotCompiledNoCodegen";
111       case kNotCompiledNonSequentialRegPair : return "kNotCompiledNonSequentialRegPair";
112       case kNotCompiledPathological : return "kNotCompiledPathological";
113       case kNotCompiledSpaceFilter : return "kNotCompiledSpaceFilter";
114       case kNotCompiledUnhandledInstruction : return "kNotCompiledUnhandledInstruction";
115       case kNotCompiledUnresolvedField : return "kNotCompiledUnresolvedField";
116       case kNotCompiledUnresolvedMethod : return "kNotCompiledUnresolvedMethod";
117       case kNotCompiledUnsupportedIsa : return "kNotCompiledUnsupportedIsa";
118       case kNotCompiledVerifyAtRuntime : return "kNotCompiledVerifyAtRuntime";
119       case kNotOptimizedDisabled : return "kNotOptimizedDisabled";
120       case kNotOptimizedRegisterAllocator : return "kNotOptimizedRegisterAllocator";
121       case kNotOptimizedTryCatch : return "kNotOptimizedTryCatch";
122       case kRemovedCheckedCast: return "kRemovedCheckedCast";
123       case kRemovedDeadInstruction: return "kRemovedDeadInstruction";
124       case kRemovedNullCheck: return "kRemovedNullCheck";
125       default: LOG(FATAL) << "invalid stat";
126     }
127     return "";
128   }
129 
130   AtomicInteger compile_stats_[kLastStat];
131 
132   DISALLOW_COPY_AND_ASSIGN(OptimizingCompilerStats);
133 };
134 
135 }  // namespace art
136 
137 #endif  // ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_
138