| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/coverage.h" | 5 #include "vm/coverage.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 // then just skip this method. | 50 // then just skip this method. |
| 51 // TODO(iposva): Maybe we should skip synthesized methods in general too. | 51 // TODO(iposva): Maybe we should skip synthesized methods in general too. |
| 52 if (function.is_abstract() || function.IsRedirectingFactory()) { | 52 if (function.is_abstract() || function.IsRedirectingFactory()) { |
| 53 return; | 53 return; |
| 54 } | 54 } |
| 55 if (function.IsNonImplicitClosureFunction() && | 55 if (function.IsNonImplicitClosureFunction() && |
| 56 (function.context_scope() == ContextScope::null())) { | 56 (function.context_scope() == ContextScope::null())) { |
| 57 // TODO(iposva): This can arise if we attempt to compile an inner function | 57 // TODO(iposva): This can arise if we attempt to compile an inner function |
| 58 // before we have compiled its enclosing function or if the enclosing | 58 // before we have compiled its enclosing function or if the enclosing |
| 59 // function failed to compile. | 59 // function failed to compile. |
| 60 OS::Print("### Coverage skipped compiling: %s\n", function.ToCString()); | |
| 61 return; | 60 return; |
| 62 } | 61 } |
| 63 const Error& err = Error::Handle( | 62 const Error& err = Error::Handle( |
| 64 isolate, Compiler::CompileFunction(isolate, function)); | 63 isolate, Compiler::CompileFunction(isolate, function)); |
| 65 if (!err.IsNull()) { | 64 if (!err.IsNull()) { |
| 66 OS::Print("### Coverage failed compiling:\n%s\n", err.ToErrorCString()); | |
| 67 return; | 65 return; |
| 68 } | 66 } |
| 69 } | 67 } |
| 70 ASSERT(function.HasCode()); | 68 ASSERT(function.HasCode()); |
| 71 | 69 |
| 72 // Print the hit counts for all IC datas. | 70 // Print the hit counts for all IC datas. |
| 73 ZoneGrowableArray<const ICData*>* ic_data_array = | 71 ZoneGrowableArray<const ICData*>* ic_data_array = |
| 74 new(isolate) ZoneGrowableArray<const ICData*>(); | 72 new(isolate) ZoneGrowableArray<const ICData*>(); |
| 75 function.RestoreICDataMap(ic_data_array); | 73 function.RestoreICDataMap(ic_data_array); |
| 76 const Code& code = Code::Handle(function.unoptimized_code()); | 74 const Code& code = Code::Handle(function.unoptimized_code()); |
| 77 const PcDescriptors& descriptors = PcDescriptors::Handle( | 75 const PcDescriptors& descriptors = PcDescriptors::Handle( |
| 78 code.pc_descriptors()); | 76 code.pc_descriptors()); |
| 79 | 77 |
| 78 const intptr_t begin_pos = function.token_pos(); |
| 79 const intptr_t end_pos = function.end_token_pos(); |
| 80 intptr_t last_line = -1; |
| 81 intptr_t last_count = 0; |
| 80 for (int j = 0; j < descriptors.Length(); j++) { | 82 for (int j = 0; j < descriptors.Length(); j++) { |
| 81 HANDLESCOPE(isolate); | 83 HANDLESCOPE(isolate); |
| 82 PcDescriptors::Kind kind = descriptors.DescriptorKind(j); | 84 PcDescriptors::Kind kind = descriptors.DescriptorKind(j); |
| 83 // Only IC based calls have counting. | 85 // Only IC based calls have counting. |
| 84 if ((kind == PcDescriptors::kIcCall) || | 86 if ((kind == PcDescriptors::kIcCall) || |
| 85 (kind == PcDescriptors::kUnoptStaticCall)) { | 87 (kind == PcDescriptors::kUnoptStaticCall)) { |
| 86 intptr_t deopt_id = descriptors.DeoptId(j); | 88 intptr_t deopt_id = descriptors.DeoptId(j); |
| 87 const ICData* ic_data= (*ic_data_array)[deopt_id]; | 89 const ICData* ic_data= (*ic_data_array)[deopt_id]; |
| 88 if (!ic_data->IsNull()) { | 90 if (!ic_data->IsNull()) { |
| 89 intptr_t token_pos = descriptors.TokenPos(j); | 91 intptr_t token_pos = descriptors.TokenPos(j); |
| 92 // Filter out descriptors that do not map to tokens in the source code. |
| 93 if (token_pos < begin_pos || |
| 94 token_pos > end_pos) { |
| 95 continue; |
| 96 } |
| 90 intptr_t line = pos_to_line[token_pos]; | 97 intptr_t line = pos_to_line[token_pos]; |
| 91 #if defined(DEBUG) | 98 #if defined(DEBUG) |
| 92 const Script& script = Script::Handle(function.script()); | 99 const Script& script = Script::Handle(function.script()); |
| 93 intptr_t test_line = -1; | 100 intptr_t test_line = -1; |
| 94 script.GetTokenLocation(token_pos, &test_line, NULL); | 101 script.GetTokenLocation(token_pos, &test_line, NULL); |
| 95 ASSERT(test_line == line); | 102 ASSERT(test_line == line); |
| 96 #endif | 103 #endif |
| 97 hits_arr.AddValue(line); | 104 // Merge hit data where possible. |
| 98 hits_arr.AddValue(ic_data->AggregateCount()); | 105 if (last_line == line) { |
| 106 last_count += ic_data->AggregateCount(); |
| 107 } else { |
| 108 if (last_line != -1) { |
| 109 hits_arr.AddValue(last_line); |
| 110 hits_arr.AddValue(last_count); |
| 111 } |
| 112 last_count = ic_data->AggregateCount(); |
| 113 last_line = line; |
| 114 } |
| 99 } | 115 } |
| 100 } | 116 } |
| 101 } | 117 } |
| 118 // Write last hit value if needed. |
| 119 if (last_line != -1) { |
| 120 hits_arr.AddValue(last_line); |
| 121 hits_arr.AddValue(last_count); |
| 122 } |
| 102 } | 123 } |
| 103 | 124 |
| 104 | 125 |
| 105 void CodeCoverage::PrintClass(const Class& cls, const JSONArray& jsarr) { | 126 void CodeCoverage::PrintClass(const Class& cls, const JSONArray& jsarr) { |
| 106 Isolate* isolate = Isolate::Current(); | 127 Isolate* isolate = Isolate::Current(); |
| 128 if (cls.EnsureIsFinalized(isolate) != Error::null()) { |
| 129 // Only classes that have been finalized do have a meaningful list of |
| 130 // functions. |
| 131 return; |
| 132 } |
| 107 Array& functions = Array::Handle(cls.functions()); | 133 Array& functions = Array::Handle(cls.functions()); |
| 108 ASSERT(!functions.IsNull()); | 134 ASSERT(!functions.IsNull()); |
| 109 Function& function = Function::Handle(); | 135 Function& function = Function::Handle(); |
| 110 Script& script = Script::Handle(); | 136 Script& script = Script::Handle(); |
| 111 String& saved_url = String::Handle(); | 137 String& saved_url = String::Handle(); |
| 112 String& url = String::Handle(); | 138 String& url = String::Handle(); |
| 113 GrowableArray<intptr_t> pos_to_line; | 139 GrowableArray<intptr_t> pos_to_line; |
| 114 int i = 0; | 140 int i = 0; |
| 115 while (i < functions.Length()) { | 141 while (i < functions.Length()) { |
| 116 HANDLESCOPE(isolate); | 142 HANDLESCOPE(isolate); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 JSONObject coverage(stream); | 244 JSONObject coverage(stream); |
| 219 coverage.AddProperty("type", "CodeCoverage"); | 245 coverage.AddProperty("type", "CodeCoverage"); |
| 220 coverage.AddProperty("id", "coverage"); | 246 coverage.AddProperty("id", "coverage"); |
| 221 { | 247 { |
| 222 JSONArray jsarr(&coverage, "coverage"); | 248 JSONArray jsarr(&coverage, "coverage"); |
| 223 for (int i = 0; i < libs.Length(); i++) { | 249 for (int i = 0; i < libs.Length(); i++) { |
| 224 lib ^= libs.At(i); | 250 lib ^= libs.At(i); |
| 225 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 251 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 226 while (it.HasNext()) { | 252 while (it.HasNext()) { |
| 227 cls = it.GetNextClass(); | 253 cls = it.GetNextClass(); |
| 228 if (cls.EnsureIsFinalized(isolate) == Error::null()) { | 254 PrintClass(cls, jsarr); |
| 229 // Only classes that have been finalized do have a meaningful list of | |
| 230 // functions. | |
| 231 PrintClass(cls, jsarr); | |
| 232 } | |
| 233 } | 255 } |
| 234 } | 256 } |
| 235 } | 257 } |
| 236 } | 258 } |
| 237 | 259 |
| 238 | 260 |
| 239 } // namespace dart | 261 } // namespace dart |
| OLD | NEW |