Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/compiler_stats.h" | 5 #include "vm/compiler_stats.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/log.h" | |
| 8 #include "vm/object_graph.h" | 9 #include "vm/object_graph.h" |
| 9 #include "vm/timer.h" | 10 #include "vm/timer.h" |
| 10 | 11 |
| 11 | 12 |
| 12 namespace dart { | 13 namespace dart { |
| 13 | 14 |
| 14 DEFINE_FLAG(bool, compiler_stats, false, "Compiler stat counters."); | 15 DEFINE_FLAG(bool, compiler_stats, false, "Compiler stat counters."); |
| 15 | 16 |
| 16 | 17 |
| 17 class TokenStreamVisitor : public ObjectGraph::Visitor { | 18 class TokenStreamVisitor : public ObjectVisitor { |
| 18 public: | 19 public: |
| 19 explicit TokenStreamVisitor(CompilerStats* compiler_stats) | 20 TokenStreamVisitor(Isolate* isolate, CompilerStats* compiler_stats) |
| 20 : obj_(Object::Handle()), stats_(compiler_stats) { | 21 : ObjectVisitor(isolate), |
| 22 obj_(Object::Handle()), | |
| 23 stats_(compiler_stats) { | |
| 21 } | 24 } |
| 22 | 25 |
| 23 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { | 26 void VisitObject(RawObject* raw_obj) { |
| 24 RawObject* raw_obj = it->Get(); | |
| 25 if (raw_obj->IsFreeListElement()) { | 27 if (raw_obj->IsFreeListElement()) { |
| 26 return kProceed; | 28 return; |
| 27 } | 29 } |
| 28 obj_ = raw_obj; | 30 obj_ = raw_obj; |
| 29 if (obj_.GetClassId() == TokenStream::kClassId) { | 31 if (obj_.GetClassId() == TokenStream::kClassId) { |
| 30 TokenStream::Iterator tkit(TokenStream::Cast(obj_), | 32 TokenStream::Iterator tkit(TokenStream::Cast(obj_), |
| 31 0, | 33 0, |
| 32 TokenStream::Iterator::kNoNewlines); | 34 TokenStream::Iterator::kNoNewlines); |
| 33 Token::Kind kind = tkit.CurrentTokenKind(); | 35 Token::Kind kind = tkit.CurrentTokenKind(); |
| 34 while (kind != Token::kEOS) { | 36 while (kind != Token::kEOS) { |
| 35 ++stats_->num_tokens_total; | 37 ++stats_->num_tokens_total; |
| 36 if (kind == Token::kIDENT) { | 38 if (kind == Token::kIDENT) { |
| 37 ++stats_->num_ident_tokens_total; | 39 ++stats_->num_ident_tokens_total; |
| 38 } else if (Token::NeedsLiteralToken(kind)) { | 40 } else if (Token::NeedsLiteralToken(kind)) { |
| 39 ++stats_->num_literal_tokens_total; | 41 ++stats_->num_literal_tokens_total; |
| 40 } | 42 } |
| 41 tkit.Advance(); | 43 tkit.Advance(); |
| 42 kind = tkit.CurrentTokenKind(); | 44 kind = tkit.CurrentTokenKind(); |
| 43 } | 45 } |
| 44 } | 46 } |
| 45 return kProceed; | |
| 46 } | 47 } |
| 47 | 48 |
| 48 private: | 49 private: |
| 49 Object& obj_; | 50 Object& obj_; |
| 50 CompilerStats* stats_; | 51 CompilerStats* stats_; |
| 51 }; | 52 }; |
| 52 | 53 |
| 53 | 54 |
| 54 CompilerStats::CompilerStats(Isolate* isolate) | 55 CompilerStats::CompilerStats(Isolate* isolate) |
| 55 : isolate_(isolate), | 56 : isolate_(isolate), |
| 56 parser_timer(true, "parser timer"), | 57 parser_timer(true, "parser timer"), |
| 57 scanner_timer(true, "scanner timer"), | 58 scanner_timer(true, "scanner timer"), |
| 58 codegen_timer(true, "codegen timer"), | 59 codegen_timer(true, "codegen timer"), |
| 59 graphbuilder_timer(true, "flow graph builder timer"), | 60 graphbuilder_timer(true, "flow graph builder timer"), |
| 60 ssa_timer(true, "flow graph SSA timer"), | 61 ssa_timer(true, "flow graph SSA timer"), |
| 61 graphinliner_timer(true, "flow graph inliner timer"), | 62 graphinliner_timer(true, "flow graph inliner timer"), |
| 62 graphinliner_parse_timer(true, "inliner parsing timer"), | 63 graphinliner_parse_timer(true, "inliner parsing timer"), |
| 63 graphinliner_build_timer(true, "inliner building timer"), | 64 graphinliner_build_timer(true, "inliner building timer"), |
| 64 graphinliner_ssa_timer(true, "inliner SSA timer"), | 65 graphinliner_ssa_timer(true, "inliner SSA timer"), |
| 65 graphinliner_opt_timer(true, "inliner optimization timer"), | 66 graphinliner_opt_timer(true, "inliner optimization timer"), |
| 66 graphinliner_subst_timer(true, "inliner substitution timer"), | 67 graphinliner_subst_timer(true, "inliner substitution timer"), |
| 67 graphoptimizer_timer(true, "flow graph optimizer timer"), | 68 graphoptimizer_timer(true, "flow graph optimizer timer"), |
| 68 graphcompiler_timer(true, "flow graph compiler timer"), | 69 graphcompiler_timer(true, "flow graph compiler timer"), |
| 69 codefinalizer_timer(true, "code finalization timer"), | 70 codefinalizer_timer(true, "code finalization timer"), |
| 70 num_tokens_total(0), | 71 num_tokens_total(0), |
| 71 num_literal_tokens_total(0), | 72 num_literal_tokens_total(0), |
| 72 num_ident_tokens_total(0), | 73 num_ident_tokens_total(0), |
| 73 num_tokens_consumed(0), | 74 num_tokens_consumed(0), |
| 74 num_token_checks(0), | |
| 75 num_tokens_lookahead(0), | |
| 76 num_cached_consts(0), | 75 num_cached_consts(0), |
| 77 num_const_cache_hits(0), | 76 num_const_cache_hits(0), |
| 78 num_classes_compiled(0), | 77 num_classes_parsed(0), |
| 78 num_class_tokens(0), | |
| 79 num_functions_parsed(0), | |
| 79 num_functions_compiled(0), | 80 num_functions_compiled(0), |
| 81 num_functions_optimized(0), | |
| 82 num_func_tokens_compiled(0), | |
| 80 num_implicit_final_getters(0), | 83 num_implicit_final_getters(0), |
| 84 num_method_extractors(0), | |
| 81 src_length(0), | 85 src_length(0), |
| 82 total_code_size(0), | 86 total_code_size(0), |
| 83 total_instr_size(0), | 87 total_instr_size(0), |
| 84 pc_desc_size(0), | 88 pc_desc_size(0), |
| 85 vardesc_size(0) { | 89 vardesc_size(0), |
| 90 text(NULL) { | |
| 86 } | 91 } |
| 87 | 92 |
| 88 | 93 |
| 89 void CompilerStats::Print() { | 94 static void PrintToStats(const char* format, ...) { |
|
Ivan Posva
2015/09/04 19:22:59
Please ensure that format and parameters are valid
hausner
2015/09/04 20:45:20
Done.
| |
| 95 Thread* thread = Thread::Current(); | |
| 96 Isolate* isolate = thread->isolate(); | |
| 97 CompilerStats* stats = isolate->compiler_stats(); | |
| 98 Zone* zone = thread->zone(); | |
| 99 ASSERT(stats != NULL); | |
| 100 va_list args; | |
| 101 va_start(args, format); | |
| 102 stats->text = zone->VPrint(format, args); | |
| 103 va_end(args); | |
| 104 } | |
| 105 | |
| 106 | |
| 107 char* CompilerStats::PrintToZone() { | |
| 90 if (!FLAG_compiler_stats) { | 108 if (!FLAG_compiler_stats) { |
| 91 return; | 109 return NULL; |
| 92 } | 110 } |
| 93 | 111 |
| 94 // Traverse the heap and compute number of tokens in all | 112 // Traverse the heap and compute number of tokens in all |
| 95 // TokenStream objects. | 113 // TokenStream objects. |
| 96 num_tokens_total = 0; | 114 num_tokens_total = 0; |
| 97 num_literal_tokens_total = 0; | 115 num_literal_tokens_total = 0; |
| 98 num_ident_tokens_total = 0; | 116 num_ident_tokens_total = 0; |
| 99 TokenStreamVisitor visitor(this); | 117 TokenStreamVisitor visitor(isolate_, this); |
| 100 ObjectGraph graph(isolate_); | 118 isolate_->heap()->IterateObjects(&visitor); |
| 101 graph.IterateObjects(&visitor); | 119 Dart::vm_isolate()->heap()->IterateObjects(&visitor); |
| 102 | 120 |
| 103 OS::Print("==== Compiler Stats for isolate '%s' ====\n", | 121 Log log(PrintToStats); |
| 122 LogBlock lb(isolate_, &log); | |
| 123 | |
| 124 log.Print("==== Compiler Stats for isolate '%s' ====\n", | |
| 104 isolate_->debugger_name()); | 125 isolate_->debugger_name()); |
| 105 OS::Print("Number of tokens: %" Pd64 "\n", num_tokens_total); | 126 log.Print("Number of tokens: %" Pd64 "\n", num_tokens_total); |
| 106 OS::Print(" Literal tokens: %" Pd64 "\n", num_literal_tokens_total); | 127 log.Print(" Literal tokens: %" Pd64 "\n", num_literal_tokens_total); |
| 107 OS::Print(" Ident tokens: %" Pd64 "\n", num_ident_tokens_total); | 128 log.Print(" Ident tokens: %" Pd64 "\n", num_ident_tokens_total); |
| 108 OS::Print("Tokens consumed: %" Pd64 " (%.2f times number of tokens)\n", | 129 log.Print("Source length: %" Pd64 " characters\n", src_length); |
| 109 num_tokens_consumed, | |
| 110 (1.0 * num_tokens_consumed) / num_tokens_total); | |
| 111 OS::Print("Tokens checked: %" Pd64 " (%.2f times tokens consumed)\n", | |
| 112 num_token_checks, (1.0 * num_token_checks) / num_tokens_consumed); | |
| 113 OS::Print("Token lookahead: %" Pd64 " (%" Pd64 "%% of tokens checked)\n", | |
| 114 num_tokens_lookahead, | |
| 115 (100 * num_tokens_lookahead) / num_token_checks); | |
| 116 OS::Print("Consts cached: %" Pd64 "\n", num_cached_consts); | |
| 117 OS::Print("Consts cache hits: %" Pd64 "\n", num_const_cache_hits); | |
| 118 | 130 |
| 119 OS::Print("Classes parsed: %" Pd64 "\n", num_classes_compiled); | 131 log.Print("==== Parser stats:\n"); |
| 120 OS::Print("Functions compiled: %" Pd64 "\n", num_functions_compiled); | 132 log.Print("Total tokens consumed: %" Pd64 "\n", num_tokens_consumed); |
| 121 OS::Print(" Impl getters: %" Pd64 "\n", num_implicit_final_getters); | 133 log.Print("Classes parsed: %" Pd64 "\n", num_classes_parsed); |
| 134 log.Print(" Tokens consumed: %" Pd64 "\n", num_class_tokens); | |
| 135 log.Print("Functions parsed: %" Pd64 "\n", num_functions_parsed); | |
| 136 log.Print(" Tokens consumed: %" Pd64 "\n", num_func_tokens_compiled); | |
| 137 log.Print("Impl getter funcs: %" Pd64 "\n", num_implicit_final_getters); | |
| 138 log.Print("Impl method extractors: %" Pd64 "\n", num_method_extractors); | |
| 139 log.Print("Consts cached: %" Pd64 "\n", num_cached_consts); | |
| 140 log.Print("Consts cache hits: %" Pd64 "\n", num_const_cache_hits); | |
| 122 | 141 |
| 123 OS::Print("Source length: %" Pd64 " characters\n", src_length); | |
| 124 int64_t scan_usecs = scanner_timer.TotalElapsedTime(); | 142 int64_t scan_usecs = scanner_timer.TotalElapsedTime(); |
| 125 OS::Print("Scanner time: %" Pd64 " msecs\n", | 143 log.Print("Scanner time: %" Pd64 " msecs\n", scan_usecs / 1000); |
| 126 scan_usecs / 1000); | |
| 127 int64_t parse_usecs = parser_timer.TotalElapsedTime(); | 144 int64_t parse_usecs = parser_timer.TotalElapsedTime(); |
| 128 OS::Print("Parser time: %" Pd64 " msecs\n", | 145 log.Print("Parser time: %" Pd64 " msecs\n", parse_usecs / 1000); |
| 129 parse_usecs / 1000); | 146 log.Print("Parser speed: %" Pd64 " tokens per msec\n", |
| 147 1000 * num_tokens_consumed / parse_usecs); | |
| 130 int64_t codegen_usecs = codegen_timer.TotalElapsedTime(); | 148 int64_t codegen_usecs = codegen_timer.TotalElapsedTime(); |
| 131 OS::Print("Code gen. time: %" Pd64 " msecs\n", | 149 |
| 150 log.Print("==== Backend stats:\n"); | |
| 151 log.Print("Code gen. time: %" Pd64 " msecs\n", | |
| 132 codegen_usecs / 1000); | 152 codegen_usecs / 1000); |
| 133 int64_t graphbuilder_usecs = graphbuilder_timer.TotalElapsedTime(); | 153 int64_t graphbuilder_usecs = graphbuilder_timer.TotalElapsedTime(); |
| 134 OS::Print(" Graph builder: %" Pd64 " msecs\n", graphbuilder_usecs / 1000); | 154 log.Print(" Graph builder: %" Pd64 " msecs\n", |
| 155 graphbuilder_usecs / 1000); | |
| 135 int64_t ssa_usecs = ssa_timer.TotalElapsedTime(); | 156 int64_t ssa_usecs = ssa_timer.TotalElapsedTime(); |
| 136 OS::Print(" Graph SSA: %" Pd64 " msecs\n", ssa_usecs / 1000); | 157 log.Print(" Graph SSA: %" Pd64 " msecs\n", ssa_usecs / 1000); |
| 137 | 158 |
| 138 int64_t graphinliner_usecs = graphinliner_timer.TotalElapsedTime(); | 159 int64_t graphinliner_usecs = graphinliner_timer.TotalElapsedTime(); |
| 139 OS::Print(" Graph inliner: %" Pd64 " msecs\n", graphinliner_usecs / 1000); | 160 log.Print(" Graph inliner: %" Pd64 " msecs\n", |
| 161 graphinliner_usecs / 1000); | |
| 140 int64_t graphinliner_parse_usecs = | 162 int64_t graphinliner_parse_usecs = |
| 141 graphinliner_parse_timer.TotalElapsedTime(); | 163 graphinliner_parse_timer.TotalElapsedTime(); |
| 142 OS::Print(" Parsing: %" Pd64 " msecs\n", | 164 log.Print(" Parsing: %" Pd64 " msecs\n", |
| 143 graphinliner_parse_usecs / 1000); | 165 graphinliner_parse_usecs / 1000); |
| 144 int64_t graphinliner_build_usecs = | 166 int64_t graphinliner_build_usecs = |
| 145 graphinliner_build_timer.TotalElapsedTime(); | 167 graphinliner_build_timer.TotalElapsedTime(); |
| 146 OS::Print(" Building: %" Pd64 " msecs\n", | 168 log.Print(" Building: %" Pd64 " msecs\n", |
| 147 graphinliner_build_usecs / 1000); | 169 graphinliner_build_usecs / 1000); |
| 148 int64_t graphinliner_ssa_usecs = graphinliner_ssa_timer.TotalElapsedTime(); | 170 int64_t graphinliner_ssa_usecs = graphinliner_ssa_timer.TotalElapsedTime(); |
| 149 OS::Print(" SSA: %" Pd64 " msecs\n", | 171 log.Print(" SSA: %" Pd64 " msecs\n", |
| 150 graphinliner_ssa_usecs / 1000); | 172 graphinliner_ssa_usecs / 1000); |
| 151 int64_t graphinliner_opt_usecs = graphinliner_opt_timer.TotalElapsedTime(); | 173 int64_t graphinliner_opt_usecs = graphinliner_opt_timer.TotalElapsedTime(); |
| 152 OS::Print(" Optimization: %" Pd64 " msecs\n", | 174 log.Print(" Optimization: %" Pd64 " msecs\n", |
| 153 graphinliner_opt_usecs / 1000); | 175 graphinliner_opt_usecs / 1000); |
| 154 int64_t graphinliner_subst_usecs = | 176 int64_t graphinliner_subst_usecs = |
| 155 graphinliner_subst_timer.TotalElapsedTime(); | 177 graphinliner_subst_timer.TotalElapsedTime(); |
| 156 OS::Print(" Substitution: %" Pd64 " msecs\n", | 178 log.Print(" Substitution: %" Pd64 " msecs\n", |
| 157 graphinliner_subst_usecs / 1000); | 179 graphinliner_subst_usecs / 1000); |
| 158 | |
| 159 int64_t graphoptimizer_usecs = graphoptimizer_timer.TotalElapsedTime(); | 180 int64_t graphoptimizer_usecs = graphoptimizer_timer.TotalElapsedTime(); |
| 160 OS::Print(" Graph optimizer: %" Pd64 " msecs\n", | 181 log.Print(" Graph optimizer: %" Pd64 " msecs\n", |
| 161 (graphoptimizer_usecs - graphinliner_usecs) / 1000); | 182 (graphoptimizer_usecs - graphinliner_usecs) / 1000); |
| 162 int64_t graphcompiler_usecs = graphcompiler_timer.TotalElapsedTime(); | 183 int64_t graphcompiler_usecs = graphcompiler_timer.TotalElapsedTime(); |
| 163 OS::Print(" Graph compiler: %" Pd64 " msecs\n", | 184 log.Print(" Graph compiler: %" Pd64 " msecs\n", |
| 164 graphcompiler_usecs / 1000); | 185 graphcompiler_usecs / 1000); |
| 165 int64_t codefinalizer_usecs = codefinalizer_timer.TotalElapsedTime(); | 186 int64_t codefinalizer_usecs = codefinalizer_timer.TotalElapsedTime(); |
| 166 OS::Print(" Code finalizer: %" Pd64 " msecs\n", | 187 log.Print(" Code finalizer: %" Pd64 " msecs\n", |
| 167 codefinalizer_usecs / 1000); | 188 codefinalizer_usecs / 1000); |
| 168 OS::Print("Compilation speed: %" Pd64 " tokens per msec\n", | 189 |
| 169 (1000 * num_tokens_total) / (parse_usecs + codegen_usecs)); | 190 log.Print("==== Compiled code stats:\n"); |
| 170 OS::Print("Code density: %" Pd64 " tokens per KB\n", | 191 log.Print("Functions parsed: %" Pd64 "\n", num_functions_parsed); |
| 171 (num_tokens_total * 1024) / total_instr_size); | 192 log.Print("Functions compiled: %" Pd64 "\n", num_functions_compiled); |
| 172 OS::Print("Instr size: %" Pd64 " KB\n", | 193 log.Print(" optimized: %" Pd64 "\n", num_functions_optimized); |
| 194 log.Print("Tokens compiled: %" Pd64 "\n", num_func_tokens_compiled); | |
| 195 log.Print("Compilation speed: %" Pd64 " tokens per msec\n", | |
| 196 (1000 * num_func_tokens_compiled) / (parse_usecs + codegen_usecs)); | |
| 197 log.Print("Code density: %" Pd64 " tokens per KB\n", | |
| 198 (num_func_tokens_compiled * 1024) / total_instr_size); | |
| 199 log.Print("Code size: %" Pd64 " KB\n", total_code_size / 1024); | |
| 200 log.Print(" Instr size: %" Pd64 " KB\n", | |
| 173 total_instr_size / 1024); | 201 total_instr_size / 1024); |
| 174 OS::Print("Pc Desc size: %" Pd64 " KB\n", pc_desc_size / 1024); | 202 log.Print(" Pc Desc size: %" Pd64 " KB\n", pc_desc_size / 1024); |
| 175 OS::Print("VarDesc size: %" Pd64 " KB\n", vardesc_size / 1024); | 203 log.Print(" VarDesc size: %" Pd64 " KB\n", vardesc_size / 1024); |
| 176 | 204 log.Flush(); |
| 177 OS::Print("Code size: %" Pd64 " KB\n", total_code_size / 1024); | 205 char* stats_text = text; |
| 206 text = NULL; | |
| 207 return stats_text; | |
| 178 } | 208 } |
| 179 | 209 |
| 180 } // namespace dart | 210 } // namespace dart |
| OLD | NEW |