Chromium Code Reviews| Index: runtime/vm/coverage.cc | 
| =================================================================== | 
| --- runtime/vm/coverage.cc (revision 27712) | 
| +++ runtime/vm/coverage.cc (working copy) | 
| @@ -4,6 +4,7 @@ | 
| #include "vm/coverage.h" | 
| +#include "include/dart_api.h" | 
| 
 
siva
2013/09/20 19:51:45
Most of our files seem to have a blank line betwee
 
Ivan Posva
2013/09/20 21:37:07
Done.
 
 | 
| #include "vm/isolate.h" | 
| #include "vm/json_stream.h" | 
| #include "vm/object.h" | 
| @@ -11,7 +12,8 @@ | 
| namespace dart { | 
| -DEFINE_FLAG(bool, print_coverage, false, "Print code coverage."); | 
| +DEFINE_FLAG(charp, coverage_dir, NULL, | 
| + "Enable writing coverage data into specified directory."); | 
| void CodeCoverage::PrintClass(const Class& cls, const JSONArray& jsarr) { | 
| const Array& functions = Array::Handle(cls.functions()); | 
| @@ -26,20 +28,22 @@ | 
| ICData& ic_data = ICData::Handle(); | 
| for (int i = 0; i < functions.Length(); i++) { | 
| function ^= functions.At(i); | 
| - if (function.HasCode()) { | 
| - JSONObject jsobj(&jsarr); | 
| - script = function.script(); | 
| - url = script.url(); | 
| - name = function.QualifiedUserVisibleName(); | 
| - jsobj.AddProperty("source", url.ToCString()); | 
| - jsobj.AddProperty("function", name.ToCString()); | 
| + JSONObject jsobj(&jsarr); | 
| + script = function.script(); | 
| + url = script.url(); | 
| + name = function.QualifiedUserVisibleName(); | 
| + jsobj.AddProperty("source", url.ToCString()); | 
| + jsobj.AddProperty("function", name.ToCString()); | 
| 
 
Michael Lippautz (Google)
2013/09/20 21:24:56
Any reason for keeping the function name? Thought
 
Ivan Posva
2013/09/20 21:37:07
Redoing the coverage data file will come in a diff
 
 | 
| + JSONArray jsarr(&jsobj, "hits"); | 
| + | 
| + if (function.HasCode()) { | 
| + // Print the hit counts for all IC datas. | 
| code = function.unoptimized_code(); | 
| ic_array = code.ExtractTypeFeedbackArray(); | 
| descriptors = code.pc_descriptors(); | 
| - JSONArray jsarr(&jsobj, "hits"); | 
| for (int j = 0; j < descriptors.Length(); j++) { | 
| PcDescriptors::Kind kind = descriptors.DescriptorKind(j); | 
| // Only IC based calls have counting. | 
| @@ -47,7 +51,7 @@ | 
| (kind == PcDescriptors::kUnoptStaticCall)) { | 
| intptr_t deopt_id = descriptors.DeoptId(j); | 
| ic_data ^= ic_array.At(deopt_id); | 
| - if (!ic_data.IsNull() && (ic_data.AggregateCount() > 0)) { | 
| + if (!ic_data.IsNull()) { | 
| intptr_t token_pos = descriptors.TokenPos(j); | 
| intptr_t line = -1; | 
| intptr_t col = -1; | 
| @@ -59,14 +63,34 @@ | 
| } | 
| } | 
| } | 
| + } else { | 
| + // The function has no code so it was never executed and thus we add one | 
| + // zero count hit at the first token index. | 
| + intptr_t line = -1; | 
| + intptr_t col = -1; | 
| + script.GetTokenLocation(function.token_pos(), &line, &col); | 
| + JSONObject func_info(&jsarr); | 
| + func_info.AddProperty("line", line); | 
| + func_info.AddProperty("col", col); | 
| + func_info.AddProperty("count", static_cast<intptr_t>(0)); | 
| } | 
| } | 
| } | 
| -void CodeCoverage::Print(Isolate* isolate) { | 
| +void CodeCoverage::Write(Isolate* isolate) { | 
| + if (FLAG_coverage_dir == NULL) { | 
| + return; | 
| + } | 
| + | 
| + Dart_FileOpenCallback file_open = Isolate::file_open_callback(); | 
| + Dart_FileWriteCallback file_write = Isolate::file_write_callback(); | 
| + Dart_FileCloseCallback file_close = Isolate::file_close_callback(); | 
| + if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) { | 
| + return; | 
| + } | 
| + | 
| JSONStream stream; | 
| - | 
| { | 
| const GrowableObjectArray& libs = GrowableObjectArray::Handle( | 
| isolate, isolate->object_store()->libraries()); | 
| @@ -87,9 +111,20 @@ | 
| } | 
| } | 
| - OS::Print("### COVERAGE DATA ###\n" | 
| - "%s\n" | 
| - "### END ###\n", stream.ToCString()); | 
| + const char* format = "%s/dart-cov-%"Pd"-%"Pd".json"; | 
| + intptr_t pid = OS::ProcessId(); | 
| + intptr_t len = OS::SNPrint(NULL, 0, format, | 
| + FLAG_coverage_dir, pid, isolate->main_port()); | 
| + char* filename = Isolate::Current()->current_zone()->Alloc<char>(len + 1);; | 
| 
 
siva
2013/09/20 19:51:45
double semi colon
 
Ivan Posva
2013/09/20 21:37:07
Done.
 
 | 
| + OS::SNPrint(filename, len + 1, format, | 
| + FLAG_coverage_dir, pid, isolate->main_port()); | 
| + void* file = (*file_open)(filename, true); | 
| + if (file == NULL) { | 
| + OS::Print("Failed to write coverage file: %s\n", filename); | 
| + return; | 
| + } | 
| + (*file_write)(stream.buffer()->buf(), stream.buffer()->length(), file); | 
| + (*file_close)(file); | 
| } | 
| } // namespace dart |