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

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
« no previous file with comments | « runtime/vm/profiler_test.cc ('k') | runtime/vm/service_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 =
278 GrowableObjectArray::Handle(cls.closures());
279 intptr_t id; 299 intptr_t id;
280 if (js->num_arguments() > 4) { 300 if (js->num_arguments() > 4) {
281 PrintError(js, "Command too long"); 301 PrintError(js, "Command too long");
282 return; 302 return;
283 } 303 }
284 CHECK_COLLECTION_ID_BOUNDS("closures", closures.Length(), js->GetArgument(3), 304 if (!GetIntegerId(js->GetArgument(3), &id)) {
285 id, js); 305 PrintError(js, "Must specify collection object id: closures/id");
286 Function& function = Function::Handle(); 306 return;
287 function ^= closures.At(id); 307 }
288 ASSERT(!function.IsNull()); 308 Function& func = Function::Handle();
289 function.PrintToJSONStream(js, false); 309 func ^= cls.ClosureFunctionFromIndex(id);
310 if (func.IsNull()) {
311 PrintError(js, "Closure function %" Pd " not found", id);
312 return;
313 }
314 func.PrintToJSONStream(js, false);
315 }
316
317
318 static void HandleClassesDispatchers(Isolate* isolate, const Class& cls,
319 JSONStream* js) {
320 intptr_t id;
321 if (js->num_arguments() > 4) {
322 PrintError(js, "Command too long");
323 return;
324 }
325 if (!GetIntegerId(js->GetArgument(3), &id)) {
326 PrintError(js, "Must specify collection object id: dispatchers/id");
327 return;
328 }
329 Function& func = Function::Handle();
330 func ^= cls.InvocationDispatcherFunctionFromIndex(id);
331 if (func.IsNull()) {
332 PrintError(js, "Dispatcher %" Pd " not found", id);
333 return;
334 }
335 func.PrintToJSONStream(js, false);
290 } 336 }
291 337
292 338
293 static void HandleClassesFunctions(Isolate* isolate, const Class& cls, 339 static void HandleClassesFunctions(Isolate* isolate, const Class& cls,
294 JSONStream* js) { 340 JSONStream* js) {
295 const Array& functions =
296 Array::Handle(cls.functions());
297 intptr_t id; 341 intptr_t id;
298 if (js->num_arguments() > 4) { 342 if (js->num_arguments() > 4) {
299 PrintError(js, "Command too long"); 343 PrintError(js, "Command too long");
300 return; 344 return;
301 } 345 }
302 CHECK_COLLECTION_ID_BOUNDS("functions", functions.Length(), 346 if (!GetIntegerId(js->GetArgument(3), &id)) {
303 js->GetArgument(3), id, js); 347 PrintError(js, "Must specify collection object id: functions/id");
304 Function& function = Function::Handle(); 348 return;
305 function ^= functions.At(id); 349 }
306 ASSERT(!function.IsNull()); 350 Function& func = Function::Handle();
307 function.PrintToJSONStream(js, false); 351 func ^= cls.FunctionFromIndex(id);
352 if (func.IsNull()) {
353 PrintError(js, "Function %" Pd " not found", id);
354 return;
355 }
356 func.PrintToJSONStream(js, false);
357 }
358
359
360 static void HandleClassesImplicitClosures(Isolate* isolate, const Class& cls,
361 JSONStream* js) {
362 intptr_t id;
363 if (js->num_arguments() > 4) {
364 PrintError(js, "Command too long");
365 return;
366 }
367 if (!GetIntegerId(js->GetArgument(3), &id)) {
368 PrintError(js, "Must specify collection object id: implicit_closures/id");
369 return;
370 }
371 Function& func = Function::Handle();
372 func ^= cls.ImplicitClosureFunctionFromIndex(id);
373 if (func.IsNull()) {
374 PrintError(js, "Implicit closure function %" Pd " not found", id);
375 return;
376 }
377 func.PrintToJSONStream(js, false);
308 } 378 }
309 379
310 380
311 static void HandleClassesFields(Isolate* isolate, const Class& cls, 381 static void HandleClassesFields(Isolate* isolate, const Class& cls,
312 JSONStream* js) { 382 JSONStream* js) {
313 const Array& fields =
314 Array::Handle(cls.fields());
315 intptr_t id; 383 intptr_t id;
316 if (js->num_arguments() > 4) { 384 if (js->num_arguments() > 4) {
317 PrintError(js, "Command too long"); 385 PrintError(js, "Command too long");
318 return; 386 return;
319 } 387 }
320 CHECK_COLLECTION_ID_BOUNDS("fields", fields.Length(), js->GetArgument(3), 388 if (!GetIntegerId(js->GetArgument(3), &id)) {
321 id, js); 389 PrintError(js, "Must specify collection object id: fields/id");
322 Field& field = Field::Handle(); 390 return;
323 field ^= fields.At(id); 391 }
324 ASSERT(!field.IsNull()); 392 Field& field = Field::Handle(cls.FieldFromIndex(id));
393 if (field.IsNull()) {
394 PrintError(js, "Field %" Pd " not found", id);
395 return;
396 }
325 field.PrintToJSONStream(js, false); 397 field.PrintToJSONStream(js, false);
326 } 398 }
327 399
328 400
329 static void HandleClasses(Isolate* isolate, JSONStream* js) { 401 static void HandleClasses(Isolate* isolate, JSONStream* js) {
330 if (js->num_arguments() == 1) { 402 if (js->num_arguments() == 1) {
331 ClassTable* table = isolate->class_table(); 403 ClassTable* table = isolate->class_table();
332 table->PrintToJSONStream(js); 404 table->PrintToJSONStream(js);
333 return; 405 return;
334 } 406 }
(...skipping 13 matching lines...) Expand all
348 cls.PrintToJSONStream(js, false); 420 cls.PrintToJSONStream(js, false);
349 return; 421 return;
350 } else if (js->num_arguments() >= 3) { 422 } else if (js->num_arguments() >= 3) {
351 const char* second = js->GetArgument(2); 423 const char* second = js->GetArgument(2);
352 if (!strcmp(second, "closures")) { 424 if (!strcmp(second, "closures")) {
353 HandleClassesClosures(isolate, cls, js); 425 HandleClassesClosures(isolate, cls, js);
354 } else if (!strcmp(second, "fields")) { 426 } else if (!strcmp(second, "fields")) {
355 HandleClassesFields(isolate, cls, js); 427 HandleClassesFields(isolate, cls, js);
356 } else if (!strcmp(second, "functions")) { 428 } else if (!strcmp(second, "functions")) {
357 HandleClassesFunctions(isolate, cls, js); 429 HandleClassesFunctions(isolate, cls, js);
430 } else if (!strcmp(second, "implicit_closures")) {
431 HandleClassesImplicitClosures(isolate, cls, js);
432 } else if (!strcmp(second, "dispatchers")) {
433 HandleClassesDispatchers(isolate, cls, js);
358 } else { 434 } else {
359 PrintError(js, "Invalid sub collection %s", second); 435 PrintError(js, "Invalid sub collection %s", second);
360 } 436 }
361 return; 437 return;
362 } 438 }
363 UNREACHABLE(); 439 UNREACHABLE();
364 } 440 }
365 441
366 442
367 static void HandleLibrary(Isolate* isolate, JSONStream* js) { 443 static void HandleLibrary(Isolate* isolate, JSONStream* js) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 } 590 }
515 591
516 592
517 static void HandleCpu(Isolate* isolate, JSONStream* js) { 593 static void HandleCpu(Isolate* isolate, JSONStream* js) {
518 JSONObject jsobj(js); 594 JSONObject jsobj(js);
519 jsobj.AddProperty("type", "CPU"); 595 jsobj.AddProperty("type", "CPU");
520 jsobj.AddProperty("architecture", CPU::Id()); 596 jsobj.AddProperty("architecture", CPU::Id());
521 } 597 }
522 598
523 599
600 static void HandleCode(Isolate* isolate, JSONStream* js) {
601 REQUIRE_COLLECTION_ID("code");
602 uintptr_t pc;
603 if (!GetUnsignedIntegerId(js->GetArgument(1), &pc, 16)) {
604 PrintError(js, "Must specify code address: code/c0deadd0.");
605 return;
606 }
607 Code& code = Code::Handle(Code::LookupCode(pc));
608 if (code.IsNull()) {
609 PrintError(js, "Could not find code at %" Px "", pc);
610 return;
611 }
612 code.PrintToJSONStream(js, false);
613 }
614
615
616 static void HandleProfile(Isolate* isolate, JSONStream* js) {
617 Profiler::PrintToJSONStream(isolate, js, true);
618 }
619
620
524 static ServiceMessageHandlerEntry __message_handlers[] = { 621 static ServiceMessageHandlerEntry __message_handlers[] = {
525 { "_echo", HandleEcho }, 622 { "_echo", HandleEcho },
526 { "classes", HandleClasses }, 623 { "classes", HandleClasses },
624 { "code", HandleCode },
527 { "cpu", HandleCpu }, 625 { "cpu", HandleCpu },
528 { "debug", HandleDebug }, 626 { "debug", HandleDebug },
529 { "libraries", HandleLibraries }, 627 { "libraries", HandleLibraries },
530 { "library", HandleLibrary }, 628 { "library", HandleLibrary },
531 { "name", HandleName }, 629 { "name", HandleName },
532 { "objecthistogram", HandleObjectHistogram}, 630 { "objecthistogram", HandleObjectHistogram},
533 { "objects", HandleObjects }, 631 { "objects", HandleObjects },
632 { "profile", HandleProfile },
534 { "scripts", HandleScripts }, 633 { "scripts", HandleScripts },
535 { "stacktrace", HandleStackTrace }, 634 { "stacktrace", HandleStackTrace },
536 }; 635 };
537 636
538 637
539 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { 638 static void HandleFallthrough(Isolate* isolate, JSONStream* js) {
540 JSONObject jsobj(js); 639 JSONObject jsobj(js);
541 jsobj.AddProperty("type", "Error"); 640 jsobj.AddProperty("type", "Error");
542 jsobj.AddProperty("text", "request not understood."); 641 jsobj.AddProperty("text", "request not understood.");
543 PrintArgumentsAndOptions(jsobj, js); 642 PrintArgumentsAndOptions(jsobj, js);
544 } 643 }
545 644
546 645
547 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { 646 static ServiceMessageHandler FindServiceMessageHandler(const char* command) {
548 intptr_t num_message_handlers = sizeof(__message_handlers) / 647 intptr_t num_message_handlers = sizeof(__message_handlers) /
549 sizeof(__message_handlers[0]); 648 sizeof(__message_handlers[0]);
550 for (intptr_t i = 0; i < num_message_handlers; i++) { 649 for (intptr_t i = 0; i < num_message_handlers; i++) {
551 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; 650 const ServiceMessageHandlerEntry& entry = __message_handlers[i];
552 if (!strcmp(command, entry.command)) { 651 if (!strcmp(command, entry.command)) {
553 return entry.handler; 652 return entry.handler;
554 } 653 }
555 } 654 }
556 return HandleFallthrough; 655 return HandleFallthrough;
557 } 656 }
558 657
559 } // namespace dart 658 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler_test.cc ('k') | runtime/vm/service_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698