| 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 <cstdio> | 5 #include <cstdio> |
| 6 | 6 |
| 7 #include "platform/utils.h" | 7 #include "platform/utils.h" |
| 8 | 8 |
| 9 #include "vm/atomic.h" | 9 #include "vm/atomic.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 stackWalker.walk(); | 217 stackWalker.walk(); |
| 218 } | 218 } |
| 219 | 219 |
| 220 | 220 |
| 221 void Profiler::PrintToJSONStream(Isolate* isolate, JSONStream* stream) { | 221 void Profiler::PrintToJSONStream(Isolate* isolate, JSONStream* stream) { |
| 222 ASSERT(isolate == Isolate::Current()); | 222 ASSERT(isolate == Isolate::Current()); |
| 223 UNIMPLEMENTED(); | 223 UNIMPLEMENTED(); |
| 224 } | 224 } |
| 225 | 225 |
| 226 | 226 |
| 227 static char* FindSymbolName(uintptr_t pc, bool* native_symbol) { | 227 static const char* FindSymbolName(uintptr_t pc, bool* symbol_name_allocated) { |
| 228 // TODO(johnmccutchan): Differentiate between symbols which can't be found | 228 // TODO(johnmccutchan): Differentiate between symbols which can't be found |
| 229 // and symbols which were GCed. (Heap::CodeContains). | 229 // and symbols which were GCed. (Heap::CodeContains). |
| 230 ASSERT(native_symbol != NULL); | 230 ASSERT(symbol_name_allocated != NULL); |
| 231 const char* symbol_name = "Unknown"; | 231 const char* symbol_name = "Unknown"; |
| 232 *native_symbol = false; | 232 *symbol_name_allocated = false; |
| 233 if (pc == 0) { | 233 if (pc == 0) { |
| 234 return const_cast<char*>(Sample::kNoFrame); | 234 return const_cast<char*>(Sample::kNoFrame); |
| 235 } | 235 } |
| 236 const Code& code = Code::Handle(Code::LookupCode(pc)); | 236 const Code& code = Code::Handle(Code::LookupCode(pc)); |
| 237 if (code.IsNull()) { | 237 if (!code.IsNull()) { |
| 238 // Possibly a native symbol. | |
| 239 char* native_name = NativeSymbolResolver::LookupSymbolName(pc); | |
| 240 if (native_name != NULL) { | |
| 241 symbol_name = native_name; | |
| 242 *native_symbol = true; | |
| 243 } | |
| 244 } else { | |
| 245 const Function& function = Function::Handle(code.function()); | 238 const Function& function = Function::Handle(code.function()); |
| 246 if (!function.IsNull()) { | 239 if (!function.IsNull()) { |
| 247 const String& name = String::Handle(function.QualifiedUserVisibleName()); | 240 const String& name = String::Handle(function.QualifiedUserVisibleName()); |
| 248 if (!name.IsNull()) { | 241 if (!name.IsNull()) { |
| 249 symbol_name = name.ToCString(); | 242 symbol_name = name.ToCString(); |
| 243 return symbol_name; |
| 250 } | 244 } |
| 251 } | 245 } |
| 246 } else { |
| 247 // Possibly a native symbol. |
| 248 char* native_name = NativeSymbolResolver::LookupSymbolName(pc); |
| 249 if (native_name != NULL) { |
| 250 symbol_name = native_name; |
| 251 *symbol_name_allocated = true; |
| 252 return symbol_name; |
| 253 } |
| 252 } | 254 } |
| 253 return const_cast<char*>(symbol_name); | 255 const intptr_t kBucketSize = 256; |
| 256 const intptr_t kBucketMask = ~(kBucketSize - 1); |
| 257 // Not a Dart symbol or a native symbol. Bin into buckets by PC. |
| 258 pc &= kBucketMask; |
| 259 { |
| 260 const intptr_t kBuffSize = 256; |
| 261 char buff[kBuffSize]; |
| 262 OS::SNPrint(&buff[0], kBuffSize-1, "Unknown [%" Px ", %" Px ")", |
| 263 pc, pc + kBucketSize); |
| 264 symbol_name = strdup(buff); |
| 265 *symbol_name_allocated = true; |
| 266 } |
| 267 return symbol_name; |
| 254 } | 268 } |
| 255 | 269 |
| 256 | 270 |
| 257 void Profiler::WriteTracingSample(Isolate* isolate, intptr_t pid, | 271 void Profiler::WriteTracingSample(Isolate* isolate, intptr_t pid, |
| 258 Sample* sample, JSONArray& events) { | 272 Sample* sample, JSONArray& events) { |
| 259 Sample::SampleType type = sample->type; | 273 Sample::SampleType type = sample->type; |
| 260 intptr_t tid = Thread::ThreadIdToIntPtr(sample->tid); | 274 intptr_t tid = Thread::ThreadIdToIntPtr(sample->tid); |
| 261 double timestamp = static_cast<double>(sample->timestamp); | 275 double timestamp = static_cast<double>(sample->timestamp); |
| 262 const char* isolate_name = isolate->name(); | 276 const char* isolate_name = isolate->name(); |
| 263 switch (type) { | 277 switch (type) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 275 begin.AddProperty("ph", "E"); | 289 begin.AddProperty("ph", "E"); |
| 276 begin.AddProperty("tid", tid); | 290 begin.AddProperty("tid", tid); |
| 277 begin.AddProperty("pid", pid); | 291 begin.AddProperty("pid", pid); |
| 278 begin.AddProperty("name", isolate_name); | 292 begin.AddProperty("name", isolate_name); |
| 279 begin.AddProperty("ts", timestamp); | 293 begin.AddProperty("ts", timestamp); |
| 280 } | 294 } |
| 281 break; | 295 break; |
| 282 case Sample::kIsolateSample: | 296 case Sample::kIsolateSample: |
| 283 // Write "B" events. | 297 // Write "B" events. |
| 284 for (int i = Sample::kNumStackFrames - 1; i >= 0; i--) { | 298 for (int i = Sample::kNumStackFrames - 1; i >= 0; i--) { |
| 285 bool native_symbol = false; | 299 bool symbol_name_allocated = false; |
| 286 char* symbol_name = FindSymbolName(sample->pcs[i], &native_symbol); | 300 const char* symbol_name = FindSymbolName(sample->pcs[i], |
| 301 &symbol_name_allocated); |
| 287 { | 302 { |
| 288 JSONObject begin(&events); | 303 JSONObject begin(&events); |
| 289 begin.AddProperty("ph", "B"); | 304 begin.AddProperty("ph", "B"); |
| 290 begin.AddProperty("tid", tid); | 305 begin.AddProperty("tid", tid); |
| 291 begin.AddProperty("pid", pid); | 306 begin.AddProperty("pid", pid); |
| 292 begin.AddProperty("name", symbol_name); | 307 begin.AddProperty("name", symbol_name); |
| 293 begin.AddProperty("ts", timestamp); | 308 begin.AddProperty("ts", timestamp); |
| 294 } | 309 } |
| 295 if (native_symbol) { | 310 if (symbol_name_allocated) { |
| 296 NativeSymbolResolver::FreeSymbolName(symbol_name); | 311 free(const_cast<char*>(symbol_name)); |
| 297 } | 312 } |
| 298 } | 313 } |
| 299 // Write "E" events. | 314 // Write "E" events. |
| 300 for (int i = 0; i < Sample::kNumStackFrames; i++) { | 315 for (int i = 0; i < Sample::kNumStackFrames; i++) { |
| 301 bool native_symbol = false; | 316 bool symbol_name_allocated = false; |
| 302 char* symbol_name = FindSymbolName(sample->pcs[i], &native_symbol); | 317 const char* symbol_name = FindSymbolName(sample->pcs[i], |
| 318 &symbol_name_allocated); |
| 303 { | 319 { |
| 304 JSONObject begin(&events); | 320 JSONObject begin(&events); |
| 305 begin.AddProperty("ph", "E"); | 321 begin.AddProperty("ph", "E"); |
| 306 begin.AddProperty("tid", tid); | 322 begin.AddProperty("tid", tid); |
| 307 begin.AddProperty("pid", pid); | 323 begin.AddProperty("pid", pid); |
| 308 begin.AddProperty("name", symbol_name); | 324 begin.AddProperty("name", symbol_name); |
| 309 begin.AddProperty("ts", timestamp); | 325 begin.AddProperty("ts", timestamp); |
| 310 } | 326 } |
| 311 if (native_symbol) { | 327 if (symbol_name_allocated) { |
| 312 NativeSymbolResolver::FreeSymbolName(symbol_name); | 328 free(const_cast<char*>(symbol_name)); |
| 313 } | 329 } |
| 314 } | 330 } |
| 315 break; | 331 break; |
| 316 default: | 332 default: |
| 317 UNIMPLEMENTED(); | 333 UNIMPLEMENTED(); |
| 318 } | 334 } |
| 319 } | 335 } |
| 320 | 336 |
| 321 | 337 |
| 322 void Profiler::WriteTracing(Isolate* isolate) { | 338 void Profiler::WriteTracing(Isolate* isolate) { |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 return false; | 550 return false; |
| 535 } | 551 } |
| 536 uintptr_t cursor = reinterpret_cast<uintptr_t>(fp); | 552 uintptr_t cursor = reinterpret_cast<uintptr_t>(fp); |
| 537 cursor += sizeof(fp); | 553 cursor += sizeof(fp); |
| 538 bool r = cursor >= lower_bound_ && cursor < stack_upper_; | 554 bool r = cursor >= lower_bound_ && cursor < stack_upper_; |
| 539 return r; | 555 return r; |
| 540 } | 556 } |
| 541 | 557 |
| 542 | 558 |
| 543 } // namespace dart | 559 } // namespace dart |
| OLD | NEW |