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 <iomanip> 21 #include <string> 22 #include <type_traits> 23 24 #include "atomic.h" 25 26 namespace art { 27 28 enum MethodCompilationStat { 29 kAttemptCompilation = 0, 30 kCompiled, 31 kInlinedInvoke, 32 kReplacedInvokeWithSimplePattern, 33 kInstructionSimplifications, 34 kInstructionSimplificationsArch, 35 kUnresolvedMethod, 36 kUnresolvedField, 37 kUnresolvedFieldNotAFastAccess, 38 kRemovedCheckedCast, 39 kRemovedDeadInstruction, 40 kRemovedNullCheck, 41 kNotCompiledSkipped, 42 kNotCompiledInvalidBytecode, 43 kNotCompiledThrowCatchLoop, 44 kNotCompiledAmbiguousArrayOp, 45 kNotCompiledHugeMethod, 46 kNotCompiledLargeMethodNoBranches, 47 kNotCompiledMalformedOpcode, 48 kNotCompiledNoCodegen, 49 kNotCompiledPathological, 50 kNotCompiledSpaceFilter, 51 kNotCompiledUnhandledInstruction, 52 kNotCompiledUnsupportedIsa, 53 kNotCompiledVerificationError, 54 kNotCompiledVerifyAtRuntime, 55 kInlinedMonomorphicCall, 56 kInlinedPolymorphicCall, 57 kMonomorphicCall, 58 kPolymorphicCall, 59 kMegamorphicCall, 60 kBooleanSimplified, 61 kIntrinsicRecognized, 62 kLoopInvariantMoved, 63 kSelectGenerated, 64 kRemovedInstanceOf, 65 kInlinedInvokeVirtualOrInterface, 66 kImplicitNullCheckGenerated, 67 kExplicitNullCheckGenerated, 68 kLastStat 69 }; 70 71 class OptimizingCompilerStats { 72 public: 73 OptimizingCompilerStats() {} 74 75 void RecordStat(MethodCompilationStat stat, size_t count = 1) { 76 compile_stats_[stat] += count; 77 } 78 79 void Log() const { 80 if (!kIsDebugBuild && !VLOG_IS_ON(compiler)) { 81 // Log only in debug builds or if the compiler is verbose. 82 return; 83 } 84 85 if (compile_stats_[kAttemptCompilation] == 0) { 86 LOG(INFO) << "Did not compile any method."; 87 } else { 88 float compiled_percent = 89 compile_stats_[kCompiled] * 100.0f / compile_stats_[kAttemptCompilation]; 90 LOG(INFO) << "Attempted compilation of " << compile_stats_[kAttemptCompilation] 91 << " methods: " << std::fixed << std::setprecision(2) 92 << compiled_percent << "% (" << compile_stats_[kCompiled] << ") compiled."; 93 94 for (int i = 0; i < kLastStat; i++) { 95 if (compile_stats_[i] != 0) { 96 LOG(INFO) << PrintMethodCompilationStat(static_cast<MethodCompilationStat>(i)) << ": " 97 << compile_stats_[i]; 98 } 99 } 100 } 101 } 102 103 private: 104 std::string PrintMethodCompilationStat(MethodCompilationStat stat) const { 105 std::string name; 106 switch (stat) { 107 case kAttemptCompilation : name = "AttemptCompilation"; break; 108 case kCompiled : name = "Compiled"; break; 109 case kInlinedInvoke : name = "InlinedInvoke"; break; 110 case kReplacedInvokeWithSimplePattern: name = "ReplacedInvokeWithSimplePattern"; break; 111 case kInstructionSimplifications: name = "InstructionSimplifications"; break; 112 case kInstructionSimplificationsArch: name = "InstructionSimplificationsArch"; break; 113 case kUnresolvedMethod : name = "UnresolvedMethod"; break; 114 case kUnresolvedField : name = "UnresolvedField"; break; 115 case kUnresolvedFieldNotAFastAccess : name = "UnresolvedFieldNotAFastAccess"; break; 116 case kRemovedCheckedCast: name = "RemovedCheckedCast"; break; 117 case kRemovedDeadInstruction: name = "RemovedDeadInstruction"; break; 118 case kRemovedNullCheck: name = "RemovedNullCheck"; break; 119 case kNotCompiledSkipped: name = "NotCompiledSkipped"; break; 120 case kNotCompiledInvalidBytecode: name = "NotCompiledInvalidBytecode"; break; 121 case kNotCompiledThrowCatchLoop : name = "NotCompiledThrowCatchLoop"; break; 122 case kNotCompiledAmbiguousArrayOp : name = "NotCompiledAmbiguousArrayOp"; break; 123 case kNotCompiledHugeMethod : name = "NotCompiledHugeMethod"; break; 124 case kNotCompiledLargeMethodNoBranches : name = "NotCompiledLargeMethodNoBranches"; break; 125 case kNotCompiledMalformedOpcode : name = "NotCompiledMalformedOpcode"; break; 126 case kNotCompiledNoCodegen : name = "NotCompiledNoCodegen"; break; 127 case kNotCompiledPathological : name = "NotCompiledPathological"; break; 128 case kNotCompiledSpaceFilter : name = "NotCompiledSpaceFilter"; break; 129 case kNotCompiledUnhandledInstruction : name = "NotCompiledUnhandledInstruction"; break; 130 case kNotCompiledUnsupportedIsa : name = "NotCompiledUnsupportedIsa"; break; 131 case kNotCompiledVerificationError : name = "NotCompiledVerificationError"; break; 132 case kNotCompiledVerifyAtRuntime : name = "NotCompiledVerifyAtRuntime"; break; 133 case kInlinedMonomorphicCall: name = "InlinedMonomorphicCall"; break; 134 case kInlinedPolymorphicCall: name = "InlinedPolymorphicCall"; break; 135 case kMonomorphicCall: name = "MonomorphicCall"; break; 136 case kPolymorphicCall: name = "PolymorphicCall"; break; 137 case kMegamorphicCall: name = "MegamorphicCall"; break; 138 case kBooleanSimplified : name = "BooleanSimplified"; break; 139 case kIntrinsicRecognized : name = "IntrinsicRecognized"; break; 140 case kLoopInvariantMoved : name = "LoopInvariantMoved"; break; 141 case kSelectGenerated : name = "SelectGenerated"; break; 142 case kRemovedInstanceOf: name = "RemovedInstanceOf"; break; 143 case kInlinedInvokeVirtualOrInterface: name = "InlinedInvokeVirtualOrInterface"; break; 144 case kImplicitNullCheckGenerated: name = "ImplicitNullCheckGenerated"; break; 145 case kExplicitNullCheckGenerated: name = "ExplicitNullCheckGenerated"; break; 146 147 case kLastStat: 148 LOG(FATAL) << "invalid stat " 149 << static_cast<std::underlying_type<MethodCompilationStat>::type>(stat); 150 UNREACHABLE(); 151 } 152 return "OptStat#" + name; 153 } 154 155 AtomicInteger compile_stats_[kLastStat]; 156 157 DISALLOW_COPY_AND_ASSIGN(OptimizingCompilerStats); 158 }; 159 160 } // namespace art 161 162 #endif // ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_ 163