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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 } | 65 } |
66 if (function.IsNonImplicitClosureFunction() && | 66 if (function.IsNonImplicitClosureFunction() && |
67 (function.context_scope() == ContextScope::null())) { | 67 (function.context_scope() == ContextScope::null())) { |
68 // TODO(iposva): This can arise if we attempt to compile an inner function | 68 // TODO(iposva): This can arise if we attempt to compile an inner function |
69 // before we have compiled its enclosing function or if the enclosing | 69 // before we have compiled its enclosing function or if the enclosing |
70 // function failed to compile. | 70 // function failed to compile. |
71 return; | 71 return; |
72 } | 72 } |
73 Thread* thread = Thread::Current(); | 73 Thread* thread = Thread::Current(); |
74 Zone* zone = thread->zone(); | 74 Zone* zone = thread->zone(); |
75 Isolate* isolate = thread->isolate(); | |
76 // Make sure we have the unoptimized code for this function available. | 75 // Make sure we have the unoptimized code for this function available. |
77 if (Compiler::EnsureUnoptimizedCode(thread, function) != Error::null()) { | 76 if (Compiler::EnsureUnoptimizedCode(thread, function) != Error::null()) { |
78 // Ignore the error and this function entirely. | 77 // Ignore the error and this function entirely. |
79 return; | 78 return; |
80 } | 79 } |
81 const Code& code = Code::Handle(zone, function.unoptimized_code()); | 80 const Code& code = Code::Handle(zone, function.unoptimized_code()); |
82 ASSERT(!code.IsNull()); | 81 ASSERT(!code.IsNull()); |
83 | 82 |
84 // Print the hit counts for all IC datas. | 83 // Print the hit counts for all IC datas. |
85 ZoneGrowableArray<const ICData*>* ic_data_array = | 84 ZoneGrowableArray<const ICData*>* ic_data_array = |
86 new(zone) ZoneGrowableArray<const ICData*>(); | 85 new(zone) ZoneGrowableArray<const ICData*>(); |
87 function.RestoreICDataMap(ic_data_array); | 86 function.RestoreICDataMap(ic_data_array); |
88 const PcDescriptors& descriptors = PcDescriptors::Handle( | 87 const PcDescriptors& descriptors = PcDescriptors::Handle( |
89 zone, code.pc_descriptors()); | 88 zone, code.pc_descriptors()); |
90 | 89 |
91 const intptr_t begin_pos = function.token_pos(); | 90 const intptr_t begin_pos = function.token_pos(); |
92 const intptr_t end_pos = function.end_token_pos(); | 91 const intptr_t end_pos = function.end_token_pos(); |
93 intptr_t last_line = -1; | 92 intptr_t last_line = -1; |
94 intptr_t last_count = 0; | 93 intptr_t last_count = 0; |
95 // Only IC based calls have counting. | 94 // Only IC based calls have counting. |
96 PcDescriptors::Iterator iter(descriptors, | 95 PcDescriptors::Iterator iter(descriptors, |
97 RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall); | 96 RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall); |
98 while (iter.MoveNext()) { | 97 while (iter.MoveNext()) { |
99 HANDLESCOPE(isolate); | 98 HANDLESCOPE(thread); |
100 const ICData* ic_data = (*ic_data_array)[iter.DeoptId()]; | 99 const ICData* ic_data = (*ic_data_array)[iter.DeoptId()]; |
101 if (!ic_data->IsNull()) { | 100 if (!ic_data->IsNull()) { |
102 const intptr_t token_pos = iter.TokenPos(); | 101 const intptr_t token_pos = iter.TokenPos(); |
103 // Filter out descriptors that do not map to tokens in the source code. | 102 // Filter out descriptors that do not map to tokens in the source code. |
104 if ((token_pos < begin_pos) || (token_pos > end_pos)) { | 103 if ((token_pos < begin_pos) || (token_pos > end_pos)) { |
105 continue; | 104 continue; |
106 } | 105 } |
107 intptr_t line = pos_to_line[token_pos]; | 106 intptr_t line = pos_to_line[token_pos]; |
108 #if defined(DEBUG) | 107 #if defined(DEBUG) |
109 const Script& script = Script::Handle(zone, function.script()); | 108 const Script& script = Script::Handle(zone, function.script()); |
(...skipping 24 matching lines...) Expand all Loading... |
134 hits_or_sites.AddValue(last_count); | 133 hits_or_sites.AddValue(last_count); |
135 } | 134 } |
136 } | 135 } |
137 | 136 |
138 | 137 |
139 void CodeCoverage::PrintClass(const Library& lib, | 138 void CodeCoverage::PrintClass(const Library& lib, |
140 const Class& cls, | 139 const Class& cls, |
141 const JSONArray& jsarr, | 140 const JSONArray& jsarr, |
142 CoverageFilter* filter, | 141 CoverageFilter* filter, |
143 bool as_call_sites) { | 142 bool as_call_sites) { |
144 Isolate* isolate = Isolate::Current(); | 143 Thread* thread = Thread::Current(); |
| 144 Isolate* isolate = thread->isolate(); |
145 if (cls.EnsureIsFinalized(isolate) != Error::null()) { | 145 if (cls.EnsureIsFinalized(isolate) != Error::null()) { |
146 // Only classes that have been finalized do have a meaningful list of | 146 // Only classes that have been finalized do have a meaningful list of |
147 // functions. | 147 // functions. |
148 return; | 148 return; |
149 } | 149 } |
150 Array& functions = Array::Handle(cls.functions()); | 150 Array& functions = Array::Handle(cls.functions()); |
151 ASSERT(!functions.IsNull()); | 151 ASSERT(!functions.IsNull()); |
152 Function& function = Function::Handle(); | 152 Function& function = Function::Handle(); |
153 Script& script = Script::Handle(); | 153 Script& script = Script::Handle(); |
154 String& saved_url = String::Handle(); | 154 String& saved_url = String::Handle(); |
155 String& url = String::Handle(); | 155 String& url = String::Handle(); |
156 GrowableArray<intptr_t> pos_to_line; | 156 GrowableArray<intptr_t> pos_to_line; |
157 int i = 0; | 157 int i = 0; |
158 while (i < functions.Length()) { | 158 while (i < functions.Length()) { |
159 HANDLESCOPE(isolate); | 159 HANDLESCOPE(thread); |
160 function ^= functions.At(i); | 160 function ^= functions.At(i); |
161 script = function.script(); | 161 script = function.script(); |
162 saved_url = script.url(); | 162 saved_url = script.url(); |
163 if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) { | 163 if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) { |
164 i++; | 164 i++; |
165 continue; | 165 continue; |
166 } | 166 } |
167 ComputeTokenPosToLineNumberMap(script, &pos_to_line); | 167 ComputeTokenPosToLineNumberMap(script, &pos_to_line); |
168 JSONObject jsobj(&jsarr); | 168 JSONObject jsobj(&jsarr); |
169 jsobj.AddProperty("source", saved_url.ToCString()); | 169 jsobj.AddProperty("source", saved_url.ToCString()); |
(...skipping 24 matching lines...) Expand all Loading... |
194 } | 194 } |
195 | 195 |
196 GrowableObjectArray& closures = | 196 GrowableObjectArray& closures = |
197 GrowableObjectArray::Handle(cls.closures()); | 197 GrowableObjectArray::Handle(cls.closures()); |
198 if (!closures.IsNull()) { | 198 if (!closures.IsNull()) { |
199 i = 0; | 199 i = 0; |
200 pos_to_line.Clear(); | 200 pos_to_line.Clear(); |
201 // We need to keep rechecking the length of the closures array, as handling | 201 // We need to keep rechecking the length of the closures array, as handling |
202 // a closure potentially adds new entries to the end. | 202 // a closure potentially adds new entries to the end. |
203 while (i < closures.Length()) { | 203 while (i < closures.Length()) { |
204 HANDLESCOPE(isolate); | 204 HANDLESCOPE(thread); |
205 function ^= closures.At(i); | 205 function ^= closures.At(i); |
206 script = function.script(); | 206 script = function.script(); |
207 saved_url = script.url(); | 207 saved_url = script.url(); |
208 if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) { | 208 if (!filter->ShouldOutputCoverageFor(lib, script, cls, function)) { |
209 i++; | 209 i++; |
210 continue; | 210 continue; |
211 } | 211 } |
212 ComputeTokenPosToLineNumberMap(script, &pos_to_line); | 212 ComputeTokenPosToLineNumberMap(script, &pos_to_line); |
213 JSONObject jsobj(&jsarr); | 213 JSONObject jsobj(&jsarr); |
214 jsobj.AddProperty("source", saved_url.ToCString()); | 214 jsobj.AddProperty("source", saved_url.ToCString()); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 cls = it.GetNextClass(); | 288 cls = it.GetNextClass(); |
289 ASSERT(!cls.IsNull()); | 289 ASSERT(!cls.IsNull()); |
290 PrintClass(lib, cls, jsarr, filter, as_call_sites); | 290 PrintClass(lib, cls, jsarr, filter, as_call_sites); |
291 } | 291 } |
292 } | 292 } |
293 } | 293 } |
294 } | 294 } |
295 | 295 |
296 | 296 |
297 } // namespace dart | 297 } // namespace dart |
OLD | NEW |