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