Home | History | Annotate | Download | only in optimizing
      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 "atomic.h"
     26 
     27 namespace art {
     28 
     29 enum MethodCompilationStat {
     30   kAttemptCompilation = 0,
     31   kCHAInline,
     32   kCompiled,
     33   kInlinedInvoke,
     34   kReplacedInvokeWithSimplePattern,
     35   kInstructionSimplifications,
     36   kInstructionSimplificationsArch,
     37   kUnresolvedMethod,
     38   kUnresolvedField,
     39   kUnresolvedFieldNotAFastAccess,
     40   kRemovedCheckedCast,
     41   kRemovedDeadInstruction,
     42   kRemovedNullCheck,
     43   kNotCompiledSkipped,
     44   kNotCompiledInvalidBytecode,
     45   kNotCompiledThrowCatchLoop,
     46   kNotCompiledAmbiguousArrayOp,
     47   kNotCompiledHugeMethod,
     48   kNotCompiledLargeMethodNoBranches,
     49   kNotCompiledMalformedOpcode,
     50   kNotCompiledNoCodegen,
     51   kNotCompiledPathological,
     52   kNotCompiledSpaceFilter,
     53   kNotCompiledUnhandledInstruction,
     54   kNotCompiledUnsupportedIsa,
     55   kNotCompiledVerificationError,
     56   kNotCompiledVerifyAtRuntime,
     57   kInlinedMonomorphicCall,
     58   kInlinedPolymorphicCall,
     59   kMonomorphicCall,
     60   kPolymorphicCall,
     61   kMegamorphicCall,
     62   kBooleanSimplified,
     63   kIntrinsicRecognized,
     64   kLoopInvariantMoved,
     65   kSelectGenerated,
     66   kRemovedInstanceOf,
     67   kInlinedInvokeVirtualOrInterface,
     68   kImplicitNullCheckGenerated,
     69   kExplicitNullCheckGenerated,
     70   kSimplifyIf,
     71   kInstructionSunk,
     72   kNotInlinedUnresolvedEntrypoint,
     73   kNotInlinedDexCache,
     74   kNotInlinedStackMaps,
     75   kNotInlinedEnvironmentBudget,
     76   kNotInlinedInstructionBudget,
     77   kNotInlinedLoopWithoutExit,
     78   kNotInlinedIrreducibleLoop,
     79   kNotInlinedAlwaysThrows,
     80   kNotInlinedInfiniteLoop,
     81   kNotInlinedTryCatch,
     82   kNotInlinedRegisterAllocator,
     83   kNotInlinedCannotBuild,
     84   kNotInlinedNotVerified,
     85   kNotInlinedCodeItem,
     86   kNotInlinedWont,
     87   kNotInlinedRecursiveBudget,
     88   kNotInlinedProxy,
     89   kLastStat
     90 };
     91 
     92 class OptimizingCompilerStats {
     93  public:
     94   OptimizingCompilerStats() {
     95     // The std::atomic<> default constructor leaves values uninitialized, so initialize them now.
     96     Reset();
     97   }
     98 
     99   void RecordStat(MethodCompilationStat stat, uint32_t count = 1) {
    100     compile_stats_[stat] += count;
    101   }
    102 
    103   void Log() const {
    104     if (!kIsDebugBuild && !VLOG_IS_ON(compiler)) {
    105       // Log only in debug builds or if the compiler is verbose.
    106       return;
    107     }
    108 
    109     if (compile_stats_[kAttemptCompilation] == 0) {
    110       LOG(INFO) << "Did not compile any method.";
    111     } else {
    112       float compiled_percent =
    113           compile_stats_[kCompiled] * 100.0f / compile_stats_[kAttemptCompilation];
    114       LOG(INFO) << "Attempted compilation of " << compile_stats_[kAttemptCompilation]
    115           << " methods: " << std::fixed << std::setprecision(2)
    116           << compiled_percent << "% (" << compile_stats_[kCompiled] << ") compiled.";
    117 
    118       for (size_t i = 0; i < kLastStat; i++) {
    119         if (compile_stats_[i] != 0) {
    120           LOG(INFO) << PrintMethodCompilationStat(static_cast<MethodCompilationStat>(i)) << ": "
    121               << compile_stats_[i];
    122         }
    123       }
    124     }
    125   }
    126 
    127   void AddTo(OptimizingCompilerStats* other_stats) {
    128     for (size_t i = 0; i != kLastStat; ++i) {
    129       uint32_t count = compile_stats_[i];
    130       if (count != 0) {
    131         other_stats->RecordStat(static_cast<MethodCompilationStat>(i), count);
    132       }
    133     }
    134   }
    135 
    136   void Reset() {
    137     for (size_t i = 0; i != kLastStat; ++i) {
    138       compile_stats_[i] = 0u;
    139     }
    140   }
    141 
    142  private:
    143   std::string PrintMethodCompilationStat(MethodCompilationStat stat) const {
    144     std::string name;
    145     switch (stat) {
    146       case kAttemptCompilation : name = "AttemptCompilation"; break;
    147       case kCHAInline : name = "CHAInline"; break;
    148       case kCompiled : name = "Compiled"; break;
    149       case kInlinedInvoke : name = "InlinedInvoke"; break;
    150       case kReplacedInvokeWithSimplePattern: name = "ReplacedInvokeWithSimplePattern"; break;
    151       case kInstructionSimplifications: name = "InstructionSimplifications"; break;
    152       case kInstructionSimplificationsArch: name = "InstructionSimplificationsArch"; break;
    153       case kUnresolvedMethod : name = "UnresolvedMethod"; break;
    154       case kUnresolvedField : name = "UnresolvedField"; break;
    155       case kUnresolvedFieldNotAFastAccess : name = "UnresolvedFieldNotAFastAccess"; break;
    156       case kRemovedCheckedCast: name = "RemovedCheckedCast"; break;
    157       case kRemovedDeadInstruction: name = "RemovedDeadInstruction"; break;
    158       case kRemovedNullCheck: name = "RemovedNullCheck"; break;
    159       case kNotCompiledSkipped: name = "NotCompiledSkipped"; break;
    160       case kNotCompiledInvalidBytecode: name = "NotCompiledInvalidBytecode"; break;
    161       case kNotCompiledThrowCatchLoop : name = "NotCompiledThrowCatchLoop"; break;
    162       case kNotCompiledAmbiguousArrayOp : name = "NotCompiledAmbiguousArrayOp"; break;
    163       case kNotCompiledHugeMethod : name = "NotCompiledHugeMethod"; break;
    164       case kNotCompiledLargeMethodNoBranches : name = "NotCompiledLargeMethodNoBranches"; break;
    165       case kNotCompiledMalformedOpcode : name = "NotCompiledMalformedOpcode"; break;
    166       case kNotCompiledNoCodegen : name = "NotCompiledNoCodegen"; break;
    167       case kNotCompiledPathological : name = "NotCompiledPathological"; break;
    168       case kNotCompiledSpaceFilter : name = "NotCompiledSpaceFilter"; break;
    169       case kNotCompiledUnhandledInstruction : name = "NotCompiledUnhandledInstruction"; break;
    170       case kNotCompiledUnsupportedIsa : name = "NotCompiledUnsupportedIsa"; break;
    171       case kNotCompiledVerificationError : name = "NotCompiledVerificationError"; break;
    172       case kNotCompiledVerifyAtRuntime : name = "NotCompiledVerifyAtRuntime"; break;
    173       case kInlinedMonomorphicCall: name = "InlinedMonomorphicCall"; break;
    174       case kInlinedPolymorphicCall: name = "InlinedPolymorphicCall"; break;
    175       case kMonomorphicCall: name = "MonomorphicCall"; break;
    176       case kPolymorphicCall: name = "PolymorphicCall"; break;
    177       case kMegamorphicCall: name = "MegamorphicCall"; break;
    178       case kBooleanSimplified : name = "BooleanSimplified"; break;
    179       case kIntrinsicRecognized : name = "IntrinsicRecognized"; break;
    180       case kLoopInvariantMoved : name = "LoopInvariantMoved"; break;
    181       case kSelectGenerated : name = "SelectGenerated"; break;
    182       case kRemovedInstanceOf: name = "RemovedInstanceOf"; break;
    183       case kInlinedInvokeVirtualOrInterface: name = "InlinedInvokeVirtualOrInterface"; break;
    184       case kImplicitNullCheckGenerated: name = "ImplicitNullCheckGenerated"; break;
    185       case kExplicitNullCheckGenerated: name = "ExplicitNullCheckGenerated"; break;
    186       case kSimplifyIf: name = "SimplifyIf"; break;
    187       case kInstructionSunk: name = "InstructionSunk"; break;
    188       case kNotInlinedUnresolvedEntrypoint: name = "NotInlinedUnresolvedEntrypoint"; break;
    189       case kNotInlinedDexCache: name = "NotInlinedDexCache"; break;
    190       case kNotInlinedStackMaps: name = "NotInlinedStackMaps"; break;
    191       case kNotInlinedEnvironmentBudget: name = "NotInlinedEnvironmentBudget"; break;
    192       case kNotInlinedInstructionBudget: name = "NotInlinedInstructionBudget"; break;
    193       case kNotInlinedLoopWithoutExit: name = "NotInlinedLoopWithoutExit"; break;
    194       case kNotInlinedIrreducibleLoop: name = "NotInlinedIrreducibleLoop"; break;
    195       case kNotInlinedAlwaysThrows: name = "NotInlinedAlwaysThrows"; break;
    196       case kNotInlinedInfiniteLoop: name = "NotInlinedInfiniteLoop"; break;
    197       case kNotInlinedTryCatch: name = "NotInlinedTryCatch"; break;
    198       case kNotInlinedRegisterAllocator: name = "NotInlinedRegisterAllocator"; break;
    199       case kNotInlinedCannotBuild: name = "NotInlinedCannotBuild"; break;
    200       case kNotInlinedNotVerified: name = "NotInlinedNotVerified"; break;
    201       case kNotInlinedCodeItem: name = "NotInlinedCodeItem"; break;
    202       case kNotInlinedWont: name = "NotInlinedWont"; break;
    203       case kNotInlinedRecursiveBudget: name = "NotInlinedRecursiveBudget"; break;
    204       case kNotInlinedProxy: name = "NotInlinedProxy"; break;
    205 
    206       case kLastStat:
    207         LOG(FATAL) << "invalid stat "
    208             << static_cast<std::underlying_type<MethodCompilationStat>::type>(stat);
    209         UNREACHABLE();
    210     }
    211     return "OptStat#" + name;
    212   }
    213 
    214   std::atomic<uint32_t> compile_stats_[kLastStat];
    215 
    216   DISALLOW_COPY_AND_ASSIGN(OptimizingCompilerStats);
    217 };
    218 
    219 }  // namespace art
    220 
    221 #endif  // ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_
    222