Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(971)

Side by Side Diff: runtime/vm/service.cc

Issue 100103011: Changes to support dprof and Observatory profiler UIs (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/service.h" 5 #include "vm/service.h"
6 6
7 #include "vm/cpu.h" 7 #include "vm/cpu.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/debugger.h" 9 #include "vm/debugger.h"
10 #include "vm/heap_histogram.h" 10 #include "vm/heap_histogram.h"
11 #include "vm/isolate.h" 11 #include "vm/isolate.h"
12 #include "vm/message.h" 12 #include "vm/message.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 #include "vm/object_id_ring.h" 14 #include "vm/object_id_ring.h"
15 #include "vm/object_store.h" 15 #include "vm/object_store.h"
16 #include "vm/port.h" 16 #include "vm/port.h"
17 #include "vm/profiler.h"
17 18
18 namespace dart { 19 namespace dart {
19 20
20 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream); 21 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream);
21 22
22 struct ServiceMessageHandlerEntry { 23 struct ServiceMessageHandlerEntry {
23 const char* command; 24 const char* command;
24 ServiceMessageHandler handler; 25 ServiceMessageHandler handler;
25 }; 26 };
26 27
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 PrintError(js, "Must specify collection object id: %s/id", collection); \ 245 PrintError(js, "Must specify collection object id: %s/id", collection); \
245 return; \ 246 return; \
246 } \ 247 } \
247 if ((id < 0) || (id >= length)) { \ 248 if ((id < 0) || (id >= length)) { \
248 PrintError(js, "%s id (%" Pd ") must be in [0, %" Pd ").", collection, id, \ 249 PrintError(js, "%s id (%" Pd ") must be in [0, %" Pd ").", collection, id, \
249 length); \ 250 length); \
250 return; \ 251 return; \
251 } 252 }
252 253
253 254
254 static bool GetIntegerId(const char* s, intptr_t* id) { 255 static bool GetIntegerId(const char* s, intptr_t* id, int base = 10) {
255 if ((s == NULL) || (*s == '\0')) { 256 if ((s == NULL) || (*s == '\0')) {
256 // Empty string. 257 // Empty string.
257 return false; 258 return false;
258 } 259 }
259 if (id == NULL) { 260 if (id == NULL) {
260 // No id pointer. 261 // No id pointer.
261 return false; 262 return false;
262 } 263 }
263 intptr_t r = 0; 264 intptr_t r = 0;
264 char* end_ptr = NULL; 265 char* end_ptr = NULL;
265 r = strtol(s, &end_ptr, 10); 266 r = strtol(s, &end_ptr, base);
266 if (end_ptr == s) { 267 if (end_ptr == s) {
267 // String was not advanced at all, cannot be valid. 268 // String was not advanced at all, cannot be valid.
268 return false; 269 return false;
270 }
271 *id = r;
272 return true;
273 }
274
275
276 static bool GetUnsignedIntegerId(const char* s, uintptr_t* id, int base = 10) {
277 if ((s == NULL) || (*s == '\0')) {
278 // Empty string.
279 return false;
280 }
281 if (id == NULL) {
282 // No id pointer.
283 return false;
284 }
285 uintptr_t r = 0;
286 char* end_ptr = NULL;
287 r = strtoul(s, &end_ptr, base);
288 if (end_ptr == s) {
289 // String was not advanced at all, cannot be valid.
290 return false;
269 } 291 }
270 *id = r; 292 *id = r;
271 return true; 293 return true;
272 } 294 }
273 295
274 296
275 static void HandleClassesClosures(Isolate* isolate, const Class& cls, 297 static void HandleClassesClosures(Isolate* isolate, const Class& cls,
276 JSONStream* js) { 298 JSONStream* js) {
277 const GrowableObjectArray& closures = 299 const GrowableObjectArray& closures =
278 GrowableObjectArray::Handle(cls.closures()); 300 GrowableObjectArray::Handle(cls.closures());
279 intptr_t id; 301 intptr_t id;
280 if (js->num_arguments() > 4) { 302 if (js->num_arguments() > 4) {
281 PrintError(js, "Command too long"); 303 PrintError(js, "Command too long");
282 return; 304 return;
283 } 305 }
284 CHECK_COLLECTION_ID_BOUNDS("closures", closures.Length(), js->GetArgument(3), 306 CHECK_COLLECTION_ID_BOUNDS("closures", closures.Length(), js->GetArgument(3),
285 id, js); 307 id, js);
286 Function& function = Function::Handle(); 308 Function& function = Function::Handle();
287 function ^= closures.At(id); 309 function ^= closures.At(id);
288 ASSERT(!function.IsNull()); 310 ASSERT(!function.IsNull());
289 function.PrintToJSONStream(js, false); 311 function.PrintToJSONStream(js, false);
290 } 312 }
291 313
292 314
315 static void HandleClassesDispatchers(Isolate* isolate, const Class& cls,
316 JSONStream* js) {
317 intptr_t id;
318 if (js->num_arguments() > 4) {
319 PrintError(js, "Command too long");
320 return;
321 }
322 if (!GetIntegerId(js->GetArgument(3), &id)) {
323 PrintError(js, "Must specify collection object id: dispatchers/id");
324 return;
325 }
326 Function& func = Function::Handle();
327 func ^= cls.InvocationDispatcherFunctionFromIndex(id);
328 if (func.IsNull()) {
329 PrintError(js, "Dispatcher %" Pd " is not a function.", id);
330 return;
331 }
332 func.PrintToJSONStream(js, false);
333 }
334
335
293 static void HandleClassesFunctions(Isolate* isolate, const Class& cls, 336 static void HandleClassesFunctions(Isolate* isolate, const Class& cls,
294 JSONStream* js) { 337 JSONStream* js, bool implicit_closure) {
295 const Array& functions = 338 const Array& functions =
296 Array::Handle(cls.functions()); 339 Array::Handle(cls.functions());
297 intptr_t id; 340 intptr_t id;
298 if (js->num_arguments() > 4) { 341 if (js->num_arguments() > 4) {
299 PrintError(js, "Command too long"); 342 PrintError(js, "Command too long");
300 return; 343 return;
301 } 344 }
302 CHECK_COLLECTION_ID_BOUNDS("functions", functions.Length(), 345 if (implicit_closure) {
303 js->GetArgument(3), id, js); 346 CHECK_COLLECTION_ID_BOUNDS("implicit_closures", functions.Length(),
347 js->GetArgument(3), id, js);
348 } else {
349 CHECK_COLLECTION_ID_BOUNDS("functions", functions.Length(),
350 js->GetArgument(3), id, js);
351 }
304 Function& function = Function::Handle(); 352 Function& function = Function::Handle();
305 function ^= functions.At(id); 353 function ^= functions.At(id);
306 ASSERT(!function.IsNull()); 354 ASSERT(!function.IsNull());
307 function.PrintToJSONStream(js, false); 355 if (!implicit_closure) {
356 function.PrintToJSONStream(js, false);
357 return;
358 }
359 if (!function.HasImplicitClosureFunction()) {
360 PrintError(js, "Function %" Pd " does not have an implicit closure.", id);
361 return;
362 }
363 Function& closure_function = Function::Handle();
364 closure_function ^= function.ImplicitClosureFunction();
365 ASSERT(!closure_function.IsNull());
366 closure_function.PrintToJSONStream(js, false);
308 } 367 }
309 368
310 369
311 static void HandleClassesFields(Isolate* isolate, const Class& cls, 370 static void HandleClassesFields(Isolate* isolate, const Class& cls,
312 JSONStream* js) { 371 JSONStream* js) {
313 const Array& fields = 372 const Array& fields =
314 Array::Handle(cls.fields()); 373 Array::Handle(cls.fields());
315 intptr_t id; 374 intptr_t id;
316 if (js->num_arguments() > 4) { 375 if (js->num_arguments() > 4) {
317 PrintError(js, "Command too long"); 376 PrintError(js, "Command too long");
(...skipping 29 matching lines...) Expand all
347 if (js->num_arguments() == 2) { 406 if (js->num_arguments() == 2) {
348 cls.PrintToJSONStream(js, false); 407 cls.PrintToJSONStream(js, false);
349 return; 408 return;
350 } else if (js->num_arguments() >= 3) { 409 } else if (js->num_arguments() >= 3) {
351 const char* second = js->GetArgument(2); 410 const char* second = js->GetArgument(2);
352 if (!strcmp(second, "closures")) { 411 if (!strcmp(second, "closures")) {
353 HandleClassesClosures(isolate, cls, js); 412 HandleClassesClosures(isolate, cls, js);
354 } else if (!strcmp(second, "fields")) { 413 } else if (!strcmp(second, "fields")) {
355 HandleClassesFields(isolate, cls, js); 414 HandleClassesFields(isolate, cls, js);
356 } else if (!strcmp(second, "functions")) { 415 } else if (!strcmp(second, "functions")) {
357 HandleClassesFunctions(isolate, cls, js); 416 HandleClassesFunctions(isolate, cls, js, false);
417 } else if (!strcmp(second, "implicit_closures")) {
418 HandleClassesFunctions(isolate, cls, js, true);
419 } else if (!strcmp(second, "dispatchers")) {
420 HandleClassesDispatchers(isolate, cls, js);
358 } else { 421 } else {
359 PrintError(js, "Invalid sub collection %s", second); 422 PrintError(js, "Invalid sub collection %s", second);
360 } 423 }
361 return; 424 return;
362 } 425 }
363 UNREACHABLE(); 426 UNREACHABLE();
364 } 427 }
365 428
366 429
367 static void HandleLibrary(Isolate* isolate, JSONStream* js) { 430 static void HandleLibrary(Isolate* isolate, JSONStream* js) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 } 577 }
515 578
516 579
517 static void HandleCpu(Isolate* isolate, JSONStream* js) { 580 static void HandleCpu(Isolate* isolate, JSONStream* js) {
518 JSONObject jsobj(js); 581 JSONObject jsobj(js);
519 jsobj.AddProperty("type", "CPU"); 582 jsobj.AddProperty("type", "CPU");
520 jsobj.AddProperty("architecture", CPU::Id()); 583 jsobj.AddProperty("architecture", CPU::Id());
521 } 584 }
522 585
523 586
587 static void HandleCode(Isolate* isolate, JSONStream* js) {
588 REQUIRE_COLLECTION_ID("code");
589 uintptr_t pc;
590 if (!GetUnsignedIntegerId(js->GetArgument(1), &pc, 16)) {
591 PrintError(js, "Must specify code address: code/c0deadd0.");
592 return;
593 }
594 Code& code = Code::Handle(Code::LookupCode(pc));
595 if (code.IsNull()) {
596 PrintError(js, "Could not find code at %" Px "", pc);
597 return;
598 }
599 code.PrintToJSONStream(js, false);
600 }
601
602
603 static void HandleProfile(Isolate* isolate, JSONStream* js) {
604 Profiler::PrintToJSONStream(isolate, js, true);
605 }
606
607
524 static ServiceMessageHandlerEntry __message_handlers[] = { 608 static ServiceMessageHandlerEntry __message_handlers[] = {
525 { "_echo", HandleEcho }, 609 { "_echo", HandleEcho },
526 { "classes", HandleClasses }, 610 { "classes", HandleClasses },
611 { "code", HandleCode },
527 { "cpu", HandleCpu }, 612 { "cpu", HandleCpu },
528 { "debug", HandleDebug }, 613 { "debug", HandleDebug },
529 { "libraries", HandleLibraries }, 614 { "libraries", HandleLibraries },
530 { "library", HandleLibrary }, 615 { "library", HandleLibrary },
531 { "name", HandleName }, 616 { "name", HandleName },
532 { "objecthistogram", HandleObjectHistogram}, 617 { "objecthistogram", HandleObjectHistogram},
533 { "objects", HandleObjects }, 618 { "objects", HandleObjects },
619 { "profile", HandleProfile },
534 { "scripts", HandleScripts }, 620 { "scripts", HandleScripts },
535 { "stacktrace", HandleStackTrace }, 621 { "stacktrace", HandleStackTrace },
536 }; 622 };
537 623
538 624
539 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { 625 static void HandleFallthrough(Isolate* isolate, JSONStream* js) {
540 JSONObject jsobj(js); 626 JSONObject jsobj(js);
541 jsobj.AddProperty("type", "Error"); 627 jsobj.AddProperty("type", "Error");
542 jsobj.AddProperty("text", "request not understood."); 628 jsobj.AddProperty("text", "request not understood.");
543 PrintArgumentsAndOptions(jsobj, js); 629 PrintArgumentsAndOptions(jsobj, js);
544 } 630 }
545 631
546 632
547 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { 633 static ServiceMessageHandler FindServiceMessageHandler(const char* command) {
548 intptr_t num_message_handlers = sizeof(__message_handlers) / 634 intptr_t num_message_handlers = sizeof(__message_handlers) /
549 sizeof(__message_handlers[0]); 635 sizeof(__message_handlers[0]);
550 for (intptr_t i = 0; i < num_message_handlers; i++) { 636 for (intptr_t i = 0; i < num_message_handlers; i++) {
551 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; 637 const ServiceMessageHandlerEntry& entry = __message_handlers[i];
552 if (!strcmp(command, entry.command)) { 638 if (!strcmp(command, entry.command)) {
553 return entry.handler; 639 return entry.handler;
554 } 640 }
555 } 641 }
556 return HandleFallthrough; 642 return HandleFallthrough;
557 } 643 }
558 644
559 } // namespace dart 645 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698