• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <atomic>
21 #include <iomanip>
22 #include <string>
23 #include <type_traits>
24 
25 #include <android-base/logging.h>
26 
27 #include "base/atomic.h"
28 #include "base/globals.h"
29 #include "base/macros.h"
30 
31 namespace art HIDDEN {
32 
33 enum class MethodCompilationStat {
34   kAttemptBytecodeCompilation = 0,
35   kAttemptIntrinsicCompilation,
36   kCompiledNativeStub,
37   kCompiledIntrinsic,
38   kCompiledBytecode,
39   kCHAInline,
40   kInlinedInvoke,
41   kInlinedLastInvoke,
42   kReplacedInvokeWithSimplePattern,
43   kInstructionSimplifications,
44   kInstructionSimplificationsArch,
45   kUnresolvedMethod,
46   kUnresolvedField,
47   kUnresolvedFieldNotAFastAccess,
48   kRemovedCheckedCast,
49   kRemovedDeadInstruction,
50   kRemovedTry,
51   kRemovedNullCheck,
52   kNotCompiledSkipped,
53   kNotCompiledInvalidBytecode,
54   kNotCompiledThrowCatchLoop,
55   kNotCompiledAmbiguousArrayOp,
56   kNotCompiledHugeMethod,
57   kNotCompiledLargeMethodNoBranches,
58   kNotCompiledMalformedOpcode,
59   kNotCompiledNoCodegen,
60   kNotCompiledPathological,
61   kNotCompiledSpaceFilter,
62   kNotCompiledUnhandledInstruction,
63   kNotCompiledUnsupportedIsa,
64   kNotCompiledInliningIrreducibleLoop,
65   kNotCompiledIrreducibleLoopAndStringInit,
66   kNotCompiledPhiEquivalentInOsr,
67   kInlinedMonomorphicCall,
68   kInlinedPolymorphicCall,
69   kMonomorphicCall,
70   kPolymorphicCall,
71   kMegamorphicCall,
72   kBooleanSimplified,
73   kIntrinsicRecognized,
74   kLoopInvariantMoved,
75   kLoopVectorized,
76   kLoopVectorizedIdiom,
77   kSelectGenerated,
78   kRemovedInstanceOf,
79   kPropagatedIfValue,
80   kInlinedInvokeVirtualOrInterface,
81   kInlinedLastInvokeVirtualOrInterface,
82   kImplicitNullCheckGenerated,
83   kExplicitNullCheckGenerated,
84   kSimplifyIf,
85   kSimplifyIfAddedPhi,
86   kSimplifyThrowingInvoke,
87   kInstructionSunk,
88   kNotInlinedUnresolvedEntrypoint,
89   kNotInlinedBss,
90   kNotInlinedDexCacheInaccessibleToCaller,
91   kNotInlinedDexCacheClinitCheck,
92   kNotInlinedStackMaps,
93   kNotInlinedEnvironmentBudget,
94   kNotInlinedInstructionBudget,
95   kNotInlinedLoopWithoutExit,
96   kNotInlinedIrreducibleLoopCallee,
97   kNotInlinedIrreducibleLoopCaller,
98   kNotInlinedAlwaysThrows,
99   kNotInlinedInfiniteLoop,
100   kNotInlinedTryCatchCallee,
101   kNotInlinedTryCatchDisabled,
102   kNotInlinedRegisterAllocator,
103   kNotInlinedCannotBuild,
104   kNotInlinedNeverInlineAnnotation,
105   kNotInlinedNotCompilable,
106   kNotInlinedNotVerified,
107   kNotInlinedCodeItem,
108   kNotInlinedEndsWithThrow,
109   kNotInlinedWont,
110   kNotInlinedRecursiveBudget,
111   kNotInlinedPolymorphicRecursiveBudget,
112   kNotInlinedProxy,
113   kNotInlinedUnresolved,
114   kNotInlinedPolymorphic,
115   kNotInlinedCustom,
116   kNotVarAnalyzedPathological,
117   kTryInline,
118   kConstructorFenceGeneratedNew,
119   kConstructorFenceGeneratedFinal,
120   kConstructorFenceRemovedLSE,
121   kConstructorFenceRemovedPFRA,
122   kConstructorFenceRemovedCFRE,
123   kPossibleWriteBarrier,
124   kRemovedWriteBarrier,
125   kBitstringTypeCheck,
126   kJitOutOfMemoryForCommit,
127   kFullLSEAllocationRemoved,
128   kFullLSEPossible,
129   kNonPartialLoadRemoved,
130   kPartialLSEPossible,
131   kPartialStoreRemoved,
132   kPartialAllocationMoved,
133   kPredicatedLoadAdded,
134   kPredicatedStoreAdded,
135   kDevirtualized,
136   kLastStat
137 };
138 std::ostream& operator<<(std::ostream& os, MethodCompilationStat rhs);
139 
140 class OptimizingCompilerStats {
141  public:
OptimizingCompilerStats()142   OptimizingCompilerStats() {
143     // The std::atomic<> default constructor leaves values uninitialized, so initialize them now.
144     Reset();
145   }
146 
147   void RecordStat(MethodCompilationStat stat, uint32_t count = 1) {
148     size_t stat_index = static_cast<size_t>(stat);
149     DCHECK_LT(stat_index, arraysize(compile_stats_));
150     compile_stats_[stat_index] += count;
151   }
152 
GetStat(MethodCompilationStat stat)153   uint32_t GetStat(MethodCompilationStat stat) const {
154     size_t stat_index = static_cast<size_t>(stat);
155     DCHECK_LT(stat_index, arraysize(compile_stats_));
156     return compile_stats_[stat_index];
157   }
158 
Log()159   void Log() const {
160     uint32_t compiled_intrinsics = GetStat(MethodCompilationStat::kCompiledIntrinsic);
161     uint32_t compiled_native_stubs = GetStat(MethodCompilationStat::kCompiledNativeStub);
162     uint32_t bytecode_attempts =
163         GetStat(MethodCompilationStat::kAttemptBytecodeCompilation);
164     if (compiled_intrinsics == 0u && compiled_native_stubs == 0u && bytecode_attempts == 0u) {
165       LOG(INFO) << "Did not compile any method.";
166     } else {
167       uint32_t compiled_bytecode_methods =
168           GetStat(MethodCompilationStat::kCompiledBytecode);
169       // Successful intrinsic compilation preempts other compilation attempts but failed intrinsic
170       // compilation shall still count towards bytecode or native stub compilation attempts.
171       uint32_t num_compilation_attempts =
172           compiled_intrinsics + compiled_native_stubs + bytecode_attempts;
173       uint32_t num_successful_compilations =
174           compiled_intrinsics + compiled_native_stubs + compiled_bytecode_methods;
175       float compiled_percent = num_successful_compilations * 100.0f / num_compilation_attempts;
176       LOG(INFO) << "Attempted compilation of "
177           << num_compilation_attempts << " methods: " << std::fixed << std::setprecision(2)
178           << compiled_percent << "% (" << num_successful_compilations << ") compiled.";
179 
180       for (size_t i = 0; i < arraysize(compile_stats_); ++i) {
181         if (compile_stats_[i] != 0) {
182           LOG(INFO) << "OptStat#" << static_cast<MethodCompilationStat>(i) << ": "
183               << compile_stats_[i];
184         }
185       }
186     }
187   }
188 
AddTo(OptimizingCompilerStats * other_stats)189   void AddTo(OptimizingCompilerStats* other_stats) {
190     for (size_t i = 0; i != arraysize(compile_stats_); ++i) {
191       uint32_t count = compile_stats_[i];
192       if (count != 0) {
193         other_stats->RecordStat(static_cast<MethodCompilationStat>(i), count);
194       }
195     }
196   }
197 
Reset()198   void Reset() {
199     for (std::atomic<uint32_t>& stat : compile_stats_) {
200       stat = 0u;
201     }
202   }
203 
204  private:
205   std::atomic<uint32_t> compile_stats_[static_cast<size_t>(MethodCompilationStat::kLastStat)];
206 
207   DISALLOW_COPY_AND_ASSIGN(OptimizingCompilerStats);
208 };
209 
210 inline void MaybeRecordStat(OptimizingCompilerStats* compiler_stats,
211                             MethodCompilationStat stat,
212                             uint32_t count = 1) {
213   if (compiler_stats != nullptr) {
214     compiler_stats->RecordStat(stat, count);
215   }
216 }
217 
218 }  // namespace art
219 
220 #endif  // ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_
221