| 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/service.h" | 5 #include "vm/service.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/globals.h" | 8 #include "platform/globals.h" |
| 9 | 9 |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 const char* c_method_name = method_name.ToCString(); | 456 const char* c_method_name = method_name.ToCString(); |
| 457 | 457 |
| 458 ServiceMethodDescriptor* method = FindMethod(c_method_name); | 458 ServiceMethodDescriptor* method = FindMethod(c_method_name); |
| 459 if (method != NULL) { | 459 if (method != NULL) { |
| 460 if (!ValidateParameters(method->parameters, &js)) { | 460 if (!ValidateParameters(method->parameters, &js)) { |
| 461 js.PostReply(); | 461 js.PostReply(); |
| 462 return; | 462 return; |
| 463 } | 463 } |
| 464 if (method->entry(isolate, &js)) { | 464 if (method->entry(isolate, &js)) { |
| 465 js.PostReply(); | 465 js.PostReply(); |
| 466 } else { |
| 467 // NOTE(turnidge): All message handlers currently return true, |
| 468 // so this case shouldn't be reached, at present. |
| 469 UNIMPLEMENTED(); |
| 466 } | 470 } |
| 467 return; | 471 return; |
| 468 } | 472 } |
| 469 | 473 |
| 470 EmbedderServiceHandler* handler = FindIsolateEmbedderHandler(c_method_name); | 474 EmbedderServiceHandler* handler = FindIsolateEmbedderHandler(c_method_name); |
| 471 if (handler == NULL) { | 475 if (handler == NULL) { |
| 472 handler = FindRootEmbedderHandler(c_method_name); | 476 handler = FindRootEmbedderHandler(c_method_name); |
| 473 } | 477 } |
| 474 | 478 |
| 475 if (handler != NULL) { | 479 if (handler != NULL) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 bool Service::NeedsGCEvents() { | 519 bool Service::NeedsGCEvents() { |
| 516 return NeedsEvents() && EventMaskHas(kEventFamilyGCMask); | 520 return NeedsEvents() && EventMaskHas(kEventFamilyGCMask); |
| 517 } | 521 } |
| 518 | 522 |
| 519 | 523 |
| 520 void Service::SetEventMask(uint32_t mask) { | 524 void Service::SetEventMask(uint32_t mask) { |
| 521 event_mask_ = mask; | 525 event_mask_ = mask; |
| 522 } | 526 } |
| 523 | 527 |
| 524 | 528 |
| 525 void Service::SendEvent(intptr_t eventId, const Object& eventMessage) { | 529 void Service::SendEvent(intptr_t eventFamilyId, |
| 530 intptr_t eventType, |
| 531 const Object& eventMessage) { |
| 526 if (!ServiceIsolate::IsRunning()) { | 532 if (!ServiceIsolate::IsRunning()) { |
| 527 return; | 533 return; |
| 528 } | 534 } |
| 529 Isolate* isolate = Isolate::Current(); | 535 Isolate* isolate = Isolate::Current(); |
| 530 ASSERT(isolate != NULL); | 536 ASSERT(isolate != NULL); |
| 531 HANDLESCOPE(isolate); | 537 HANDLESCOPE(isolate); |
| 532 | 538 |
| 533 // Construct a list of the form [eventId, eventMessage]. | 539 // Construct a list of the form [eventFamilyId, eventMessage]. |
| 540 // |
| 541 // TODO(turnidge): Revisit passing the eventFamilyId here at all. |
| 534 const Array& list = Array::Handle(Array::New(2)); | 542 const Array& list = Array::Handle(Array::New(2)); |
| 535 ASSERT(!list.IsNull()); | 543 ASSERT(!list.IsNull()); |
| 536 list.SetAt(0, Integer::Handle(Integer::New(eventId))); | 544 list.SetAt(0, Integer::Handle(Integer::New(eventFamilyId))); |
| 537 list.SetAt(1, eventMessage); | 545 list.SetAt(1, eventMessage); |
| 538 | 546 |
| 539 // Push the event to port_. | 547 // Push the event to port_. |
| 540 uint8_t* data = NULL; | 548 uint8_t* data = NULL; |
| 541 MessageWriter writer(&data, &allocator, false); | 549 MessageWriter writer(&data, &allocator, false); |
| 542 writer.WriteMessage(list); | 550 writer.WriteMessage(list); |
| 543 intptr_t len = writer.BytesWritten(); | 551 intptr_t len = writer.BytesWritten(); |
| 544 if (FLAG_trace_service) { | 552 if (FLAG_trace_service) { |
| 545 OS::Print("vm-service: Pushing event of type %" Pd ", len %" Pd "\n", | 553 OS::Print("vm-service: Pushing event of type %" Pd ", len %" Pd "\n", |
| 546 eventId, len); | 554 eventType, len); |
| 547 } | 555 } |
| 548 // TODO(turnidge): For now we ignore failure to send an event. Revisit? | 556 // TODO(turnidge): For now we ignore failure to send an event. Revisit? |
| 549 PortMap::PostMessage( | 557 PortMap::PostMessage( |
| 550 new Message(ServiceIsolate::Port(), data, len, Message::kNormalPriority)); | 558 new Message(ServiceIsolate::Port(), data, len, Message::kNormalPriority)); |
| 551 } | 559 } |
| 552 | 560 |
| 553 | 561 |
| 554 void Service::SendEvent(intptr_t eventId, | 562 void Service::SendEvent(intptr_t eventFamilyId, |
| 555 const String& meta, | 563 const String& meta, |
| 556 const uint8_t* data, | 564 const uint8_t* data, |
| 557 intptr_t size) { | 565 intptr_t size) { |
| 558 // Bitstream: [meta data size (big-endian 64 bit)] [meta data (UTF-8)] [data] | 566 // Bitstream: [meta data size (big-endian 64 bit)] [meta data (UTF-8)] [data] |
| 559 const intptr_t meta_bytes = Utf8::Length(meta); | 567 const intptr_t meta_bytes = Utf8::Length(meta); |
| 560 const intptr_t total_bytes = sizeof(uint64_t) + meta_bytes + size; | 568 const intptr_t total_bytes = sizeof(uint64_t) + meta_bytes + size; |
| 561 const TypedData& message = TypedData::Handle( | 569 const TypedData& message = TypedData::Handle( |
| 562 TypedData::New(kTypedDataUint8ArrayCid, total_bytes)); | 570 TypedData::New(kTypedDataUint8ArrayCid, total_bytes)); |
| 563 intptr_t offset = 0; | 571 intptr_t offset = 0; |
| 564 // TODO(koda): Rename these methods SetHostUint64, etc. | 572 // TODO(koda): Rename these methods SetHostUint64, etc. |
| 565 message.SetUint64(0, Utils::HostToBigEndian64(meta_bytes)); | 573 message.SetUint64(0, Utils::HostToBigEndian64(meta_bytes)); |
| 566 offset += sizeof(uint64_t); | 574 offset += sizeof(uint64_t); |
| 567 { | 575 { |
| 568 NoGCScope no_gc; | 576 NoGCScope no_gc; |
| 569 meta.ToUTF8(static_cast<uint8_t*>(message.DataAddr(offset)), meta_bytes); | 577 meta.ToUTF8(static_cast<uint8_t*>(message.DataAddr(offset)), meta_bytes); |
| 570 offset += meta_bytes; | 578 offset += meta_bytes; |
| 571 } | 579 } |
| 572 // TODO(koda): It would be nice to avoid this copy (requires changes to | 580 // TODO(koda): It would be nice to avoid this copy (requires changes to |
| 573 // MessageWriter code). | 581 // MessageWriter code). |
| 574 { | 582 { |
| 575 NoGCScope no_gc; | 583 NoGCScope no_gc; |
| 576 memmove(message.DataAddr(offset), data, size); | 584 memmove(message.DataAddr(offset), data, size); |
| 577 offset += size; | 585 offset += size; |
| 578 } | 586 } |
| 579 ASSERT(offset == total_bytes); | 587 ASSERT(offset == total_bytes); |
| 580 SendEvent(eventId, message); | 588 // TODO(turnidge): Pass the real eventType here. |
| 589 SendEvent(eventFamilyId, 0, message); |
| 581 } | 590 } |
| 582 | 591 |
| 583 | 592 |
| 584 void Service::HandleGCEvent(GCEvent* event) { | 593 void Service::HandleGCEvent(GCEvent* event) { |
| 585 JSONStream js; | 594 JSONStream js; |
| 586 event->PrintJSON(&js); | 595 event->PrintJSON(&js); |
| 587 const String& message = String::Handle(String::New(js.ToCString())); | 596 const String& message = String::Handle(String::New(js.ToCString())); |
| 588 SendEvent(kEventFamilyGC, message); | 597 // TODO(turnidge): Pass the real eventType here. |
| 598 SendEvent(kEventFamilyGC, 0, message); |
| 589 } | 599 } |
| 590 | 600 |
| 591 | 601 |
| 592 void Service::HandleEvent(ServiceEvent* event) { | 602 void Service::HandleEvent(ServiceEvent* event) { |
| 593 JSONStream js; | 603 JSONStream js; |
| 594 event->PrintJSON(&js); | 604 event->PrintJSON(&js); |
| 595 const String& message = String::Handle(String::New(js.ToCString())); | 605 const String& message = String::Handle(String::New(js.ToCString())); |
| 596 SendEvent(kEventFamilyDebug, message); | 606 SendEvent(kEventFamilyDebug, event->type(), message); |
| 597 } | 607 } |
| 598 | 608 |
| 599 | 609 |
| 600 class EmbedderServiceHandler { | 610 class EmbedderServiceHandler { |
| 601 public: | 611 public: |
| 602 explicit EmbedderServiceHandler(const char* name) : name_(NULL), | 612 explicit EmbedderServiceHandler(const char* name) : name_(NULL), |
| 603 callback_(NULL), | 613 callback_(NULL), |
| 604 user_data_(NULL), | 614 user_data_(NULL), |
| 605 next_(NULL) { | 615 next_(NULL) { |
| 606 ASSERT(name != NULL); | 616 ASSERT(name != NULL); |
| (...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 result.PrintJSON(js, true); | 1522 result.PrintJSON(js, true); |
| 1513 return true; | 1523 return true; |
| 1514 } | 1524 } |
| 1515 PrintError(js, "%s: Invalid 'targetId' parameter value: " | 1525 PrintError(js, "%s: Invalid 'targetId' parameter value: " |
| 1516 "id '%s' does not correspond to a " | 1526 "id '%s' does not correspond to a " |
| 1517 "library, class, or instance", js->method(), target_id); | 1527 "library, class, or instance", js->method(), target_id); |
| 1518 return true; | 1528 return true; |
| 1519 } | 1529 } |
| 1520 | 1530 |
| 1521 | 1531 |
| 1532 static const MethodParameter* eval_frame_params[] = { |
| 1533 ISOLATE_PARAMETER, |
| 1534 new UIntParameter("frame", true), |
| 1535 new MethodParameter("expression", true), |
| 1536 NULL, |
| 1537 }; |
| 1538 |
| 1539 |
| 1540 static bool EvalFrame(Isolate* isolate, JSONStream* js) { |
| 1541 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); |
| 1542 intptr_t framePos = UIntParameter::Parse(js->LookupParam("frame")); |
| 1543 if (framePos > stack->Length()) { |
| 1544 PrintInvalidParamError(js, "frame"); |
| 1545 return true; |
| 1546 } |
| 1547 ActivationFrame* frame = stack->FrameAt(framePos); |
| 1548 |
| 1549 const char* expr = js->LookupParam("expression"); |
| 1550 const String& expr_str = String::Handle(isolate, String::New(expr)); |
| 1551 |
| 1552 const Object& result = Object::Handle(frame->Evaluate(expr_str)); |
| 1553 result.PrintJSON(js, true); |
| 1554 return true; |
| 1555 } |
| 1556 |
| 1557 |
| 1522 static const MethodParameter* get_call_site_data_params[] = { | 1558 static const MethodParameter* get_call_site_data_params[] = { |
| 1523 ISOLATE_PARAMETER, | 1559 ISOLATE_PARAMETER, |
| 1524 new IdParameter("targetId", true), | 1560 new IdParameter("targetId", true), |
| 1525 NULL, | 1561 NULL, |
| 1526 }; | 1562 }; |
| 1527 | 1563 |
| 1528 | 1564 |
| 1529 static bool GetCallSiteData(Isolate* isolate, JSONStream* js) { | 1565 static bool GetCallSiteData(Isolate* isolate, JSONStream* js) { |
| 1530 const char* target_id = js->LookupParam("targetId"); | 1566 const char* target_id = js->LookupParam("targetId"); |
| 1531 Object& obj = Object::Handle(LookupHeapObject(isolate, target_id, NULL)); | 1567 Object& obj = Object::Handle(LookupHeapObject(isolate, target_id, NULL)); |
| (...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2499 { "_triggerEchoEvent", _TriggerEchoEvent, | 2535 { "_triggerEchoEvent", _TriggerEchoEvent, |
| 2500 NULL }, | 2536 NULL }, |
| 2501 { "addBreakpoint", AddBreakpoint, | 2537 { "addBreakpoint", AddBreakpoint, |
| 2502 add_breakpoint_params }, | 2538 add_breakpoint_params }, |
| 2503 { "addBreakpointAtEntry", AddBreakpointAtEntry, | 2539 { "addBreakpointAtEntry", AddBreakpointAtEntry, |
| 2504 add_breakpoint_at_entry_params }, | 2540 add_breakpoint_at_entry_params }, |
| 2505 { "clearCpuProfile", ClearCpuProfile, | 2541 { "clearCpuProfile", ClearCpuProfile, |
| 2506 clear_cpu_profile_params }, | 2542 clear_cpu_profile_params }, |
| 2507 { "eval", Eval, | 2543 { "eval", Eval, |
| 2508 eval_params }, | 2544 eval_params }, |
| 2545 { "evalFrame", EvalFrame, |
| 2546 eval_frame_params }, |
| 2509 { "getAllocationProfile", GetAllocationProfile, | 2547 { "getAllocationProfile", GetAllocationProfile, |
| 2510 get_allocation_profile_params }, | 2548 get_allocation_profile_params }, |
| 2511 { "getCallSiteData", GetCallSiteData, | 2549 { "getCallSiteData", GetCallSiteData, |
| 2512 get_call_site_data_params }, | 2550 get_call_site_data_params }, |
| 2513 { "getClassList", GetClassList, | 2551 { "getClassList", GetClassList, |
| 2514 get_class_list_params }, | 2552 get_class_list_params }, |
| 2515 { "getCoverage", GetCoverage, | 2553 { "getCoverage", GetCoverage, |
| 2516 get_coverage_params }, | 2554 get_coverage_params }, |
| 2517 { "getCpuProfile", GetCpuProfile, | 2555 { "getCpuProfile", GetCpuProfile, |
| 2518 get_cpu_profile_params }, | 2556 get_cpu_profile_params }, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2570 ServiceMethodDescriptor& method = service_methods_[i]; | 2608 ServiceMethodDescriptor& method = service_methods_[i]; |
| 2571 if (strcmp(method_name, method.name) == 0) { | 2609 if (strcmp(method_name, method.name) == 0) { |
| 2572 return &method; | 2610 return &method; |
| 2573 } | 2611 } |
| 2574 } | 2612 } |
| 2575 return NULL; | 2613 return NULL; |
| 2576 } | 2614 } |
| 2577 | 2615 |
| 2578 | 2616 |
| 2579 } // namespace dart | 2617 } // namespace dart |
| OLD | NEW |