| 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" |
| 11 #include "vm/coverage.h" | 11 #include "vm/coverage.h" |
| 12 #include "vm/cpu.h" | 12 #include "vm/cpu.h" |
| 13 #include "vm/dart_api_impl.h" | 13 #include "vm/dart_api_impl.h" |
| 14 #include "vm/dart_entry.h" | 14 #include "vm/dart_entry.h" |
| 15 #include "vm/debugger.h" | 15 #include "vm/debugger.h" |
| 16 #include "vm/isolate.h" | 16 #include "vm/isolate.h" |
| 17 #include "vm/message.h" | 17 #include "vm/message.h" |
| 18 #include "vm/message_handler.h" | 18 #include "vm/message_handler.h" |
| 19 #include "vm/native_entry.h" | 19 #include "vm/native_entry.h" |
| 20 #include "vm/native_arguments.h" | 20 #include "vm/native_arguments.h" |
| 21 #include "vm/object.h" | 21 #include "vm/object.h" |
| 22 #include "vm/object_graph.h" | 22 #include "vm/object_graph.h" |
| 23 #include "vm/object_id_ring.h" | 23 #include "vm/object_id_ring.h" |
| 24 #include "vm/object_store.h" | 24 #include "vm/object_store.h" |
| 25 #include "vm/port.h" | 25 #include "vm/port.h" |
| 26 #include "vm/profiler.h" | 26 #include "vm/profiler.h" |
| 27 #include "vm/reusable_handles.h" | 27 #include "vm/reusable_handles.h" |
| 28 #include "vm/stack_frame.h" | 28 #include "vm/stack_frame.h" |
| 29 #include "vm/symbols.h" | 29 #include "vm/symbols.h" |
| 30 #include "vm/unicode.h" |
| 30 #include "vm/version.h" | 31 #include "vm/version.h" |
| 31 | 32 |
| 32 | 33 |
| 33 namespace dart { | 34 namespace dart { |
| 34 | 35 |
| 35 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests."); | 36 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests."); |
| 36 DEFINE_FLAG(bool, trace_service_pause_events, false, | 37 DEFINE_FLAG(bool, trace_service_pause_events, false, |
| 37 "Trace VM service isolate pause events."); | 38 "Trace VM service isolate pause events."); |
| 38 DECLARE_FLAG(bool, enable_type_checks); | 39 DECLARE_FLAG(bool, enable_type_checks); |
| 39 DECLARE_FLAG(bool, enable_asserts); | 40 DECLARE_FLAG(bool, enable_asserts); |
| (...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 JSONObject jsobj(&jsarr); | 783 JSONObject jsobj(&jsarr); |
| 783 frame->PrintToJSONObject(&jsobj); | 784 frame->PrintToJSONObject(&jsobj); |
| 784 // TODO(turnidge): Implement depth differently -- differentiate | 785 // TODO(turnidge): Implement depth differently -- differentiate |
| 785 // inlined frames. | 786 // inlined frames. |
| 786 jsobj.AddProperty("depth", i); | 787 jsobj.AddProperty("depth", i); |
| 787 } | 788 } |
| 788 return true; | 789 return true; |
| 789 } | 790 } |
| 790 | 791 |
| 791 | 792 |
| 792 static bool HandleIsolateEcho(Isolate* isolate, JSONStream* js) { | 793 static bool HandleCommonEcho(JSONObject* jsobj, JSONStream* js) { |
| 794 jsobj->AddProperty("type", "message"); |
| 795 PrintArgumentsAndOptions(*jsobj, js); |
| 796 return true; |
| 797 } |
| 798 |
| 799 |
| 800 void Service::SendEchoEvent(Isolate* isolate) { |
| 801 JSONStream js; |
| 802 { |
| 803 JSONObject jsobj(&js); |
| 804 jsobj.AddProperty("type", "ServiceEvent"); |
| 805 jsobj.AddPropertyF("id", "_echoEvent"); |
| 806 jsobj.AddProperty("eventType", "_Echo"); |
| 807 jsobj.AddProperty("isolate", isolate); |
| 808 } |
| 809 const String& message = String::Handle(String::New(js.ToCString())); |
| 810 uint8_t data[] = {0, 128, 255}; |
| 811 // TODO(koda): Add 'testing' event family. |
| 812 SendEvent(kEventFamilyDebug, message, data, sizeof(data)); |
| 813 } |
| 814 |
| 815 |
| 816 bool HandleIsolateEcho(Isolate* isolate, JSONStream* js) { |
| 793 JSONObject jsobj(js); | 817 JSONObject jsobj(js); |
| 794 jsobj.AddProperty("type", "message"); | 818 jsobj.AddProperty("id", "_echo"); |
| 795 PrintArgumentsAndOptions(jsobj, js); | 819 if (js->num_arguments() == 2 && strcmp(js->GetArgument(1), "event") == 0) { |
| 796 return true; | 820 Service::SendEchoEvent(isolate); |
| 821 } |
| 822 return HandleCommonEcho(&jsobj, js); |
| 797 } | 823 } |
| 798 | 824 |
| 799 | 825 |
| 800 // Print an error message if there is no ID argument. | 826 // Print an error message if there is no ID argument. |
| 801 #define REQUIRE_COLLECTION_ID(collection) \ | 827 #define REQUIRE_COLLECTION_ID(collection) \ |
| 802 if (js->num_arguments() == 1) { \ | 828 if (js->num_arguments() == 1) { \ |
| 803 PrintError(js, "Must specify collection object id: /%s/id", collection); \ | 829 PrintError(js, "Must specify collection object id: /%s/id", collection); \ |
| 804 return true; \ | 830 return true; \ |
| 805 } | 831 } |
| 806 | 832 |
| (...skipping 1509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2316 js.PostReply(); | 2342 js.PostReply(); |
| 2317 } | 2343 } |
| 2318 } | 2344 } |
| 2319 } | 2345 } |
| 2320 } | 2346 } |
| 2321 } | 2347 } |
| 2322 | 2348 |
| 2323 | 2349 |
| 2324 static bool HandleRootEcho(JSONStream* js) { | 2350 static bool HandleRootEcho(JSONStream* js) { |
| 2325 JSONObject jsobj(js); | 2351 JSONObject jsobj(js); |
| 2326 jsobj.AddProperty("type", "message"); | 2352 jsobj.AddProperty("id", "_echo"); |
| 2327 PrintArgumentsAndOptions(jsobj, js); | 2353 return HandleCommonEcho(&jsobj, js); |
| 2328 return true; | |
| 2329 } | 2354 } |
| 2330 | 2355 |
| 2331 | 2356 |
| 2332 class ServiceIsolateVisitor : public IsolateVisitor { | 2357 class ServiceIsolateVisitor : public IsolateVisitor { |
| 2333 public: | 2358 public: |
| 2334 explicit ServiceIsolateVisitor(JSONArray* jsarr) | 2359 explicit ServiceIsolateVisitor(JSONArray* jsarr) |
| 2335 : jsarr_(jsarr) { | 2360 : jsarr_(jsarr) { |
| 2336 } | 2361 } |
| 2337 | 2362 |
| 2338 virtual ~ServiceIsolateVisitor() {} | 2363 virtual ~ServiceIsolateVisitor() {} |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2431 return entry.handler; | 2456 return entry.handler; |
| 2432 } | 2457 } |
| 2433 } | 2458 } |
| 2434 if (FLAG_trace_service) { | 2459 if (FLAG_trace_service) { |
| 2435 OS::Print("Service has no root message handler for <%s>\n", command); | 2460 OS::Print("Service has no root message handler for <%s>\n", command); |
| 2436 } | 2461 } |
| 2437 return NULL; | 2462 return NULL; |
| 2438 } | 2463 } |
| 2439 | 2464 |
| 2440 | 2465 |
| 2441 void Service::SendEvent(intptr_t eventId, const String& eventMessage) { | 2466 void Service::SendEvent(intptr_t eventId, const Object& eventMessage) { |
| 2442 if (!IsRunning()) { | 2467 if (!IsRunning()) { |
| 2443 return; | 2468 return; |
| 2444 } | 2469 } |
| 2445 Isolate* isolate = Isolate::Current(); | 2470 Isolate* isolate = Isolate::Current(); |
| 2446 ASSERT(isolate != NULL); | 2471 ASSERT(isolate != NULL); |
| 2447 HANDLESCOPE(isolate); | 2472 HANDLESCOPE(isolate); |
| 2448 | 2473 |
| 2449 // Construct a list of the form [eventId, eventMessage]. | 2474 // Construct a list of the form [eventId, eventMessage]. |
| 2450 const Array& list = Array::Handle(Array::New(2)); | 2475 const Array& list = Array::Handle(Array::New(2)); |
| 2451 ASSERT(!list.IsNull()); | 2476 ASSERT(!list.IsNull()); |
| 2452 list.SetAt(0, Integer::Handle(Integer::New(eventId))); | 2477 list.SetAt(0, Integer::Handle(Integer::New(eventId))); |
| 2453 list.SetAt(1, eventMessage); | 2478 list.SetAt(1, eventMessage); |
| 2454 | 2479 |
| 2455 // Push the event to port_. | 2480 // Push the event to port_. |
| 2456 uint8_t* data = NULL; | 2481 uint8_t* data = NULL; |
| 2457 MessageWriter writer(&data, &allocator); | 2482 MessageWriter writer(&data, &allocator); |
| 2458 writer.WriteMessage(list); | 2483 writer.WriteMessage(list); |
| 2459 intptr_t len = writer.BytesWritten(); | 2484 intptr_t len = writer.BytesWritten(); |
| 2460 if (FLAG_trace_service) { | 2485 if (FLAG_trace_service) { |
| 2461 OS::Print("Pushing event of type %" Pd ", len %" Pd "\n", eventId, len); | 2486 OS::Print("Pushing event of type %" Pd ", len %" Pd "\n", eventId, len); |
| 2462 } | 2487 } |
| 2463 // TODO(turnidge): For now we ignore failure to send an event. Revisit? | 2488 // TODO(turnidge): For now we ignore failure to send an event. Revisit? |
| 2464 PortMap::PostMessage( | 2489 PortMap::PostMessage( |
| 2465 new Message(port_, data, len, Message::kNormalPriority)); | 2490 new Message(port_, data, len, Message::kNormalPriority)); |
| 2466 } | 2491 } |
| 2467 | 2492 |
| 2468 | 2493 |
| 2494 void Service::SendEvent(intptr_t eventId, |
| 2495 const String& meta, |
| 2496 const uint8_t* data, |
| 2497 intptr_t size) { |
| 2498 // Bitstream: [meta data size (big-endian 64 bit)] [meta data (UTF-8)] [data] |
| 2499 const intptr_t meta_bytes = Utf8::Length(meta); |
| 2500 const intptr_t total_bytes = sizeof(uint64_t) + meta_bytes + size; |
| 2501 const TypedData& message = TypedData::Handle( |
| 2502 TypedData::New(kTypedDataUint8ArrayCid, total_bytes)); |
| 2503 intptr_t offset = 0; |
| 2504 // TODO(koda): Rename these methods SetHostUint64, etc. |
| 2505 message.SetUint64(0, Utils::HostToBigEndian64(meta_bytes)); |
| 2506 offset += sizeof(uint64_t); |
| 2507 { |
| 2508 NoGCScope no_gc; |
| 2509 meta.ToUTF8(static_cast<uint8_t*>(message.DataAddr(offset)), meta_bytes); |
| 2510 offset += meta_bytes; |
| 2511 } |
| 2512 // TODO(koda): It would be nice to avoid this copy (requires changes to |
| 2513 // MessageWriter code). |
| 2514 memmove(message.DataAddr(offset), data, size); |
| 2515 offset += size; |
| 2516 ASSERT(offset == total_bytes); |
| 2517 SendEvent(eventId, message); |
| 2518 } |
| 2519 |
| 2520 |
| 2469 void Service::HandleGCEvent(GCEvent* event) { | 2521 void Service::HandleGCEvent(GCEvent* event) { |
| 2470 JSONStream js; | 2522 JSONStream js; |
| 2471 event->PrintJSON(&js); | 2523 event->PrintJSON(&js); |
| 2472 const String& message = String::Handle(String::New(js.ToCString())); | 2524 const String& message = String::Handle(String::New(js.ToCString())); |
| 2473 SendEvent(kEventFamilyGC, message); | 2525 SendEvent(kEventFamilyGC, message); |
| 2474 } | 2526 } |
| 2475 | 2527 |
| 2476 | 2528 |
| 2477 void Service::HandleDebuggerEvent(DebuggerEvent* event) { | 2529 void Service::HandleDebuggerEvent(DebuggerEvent* event) { |
| 2478 JSONStream js; | 2530 JSONStream js; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2571 while (current != NULL) { | 2623 while (current != NULL) { |
| 2572 if (strcmp(name, current->name()) == 0) { | 2624 if (strcmp(name, current->name()) == 0) { |
| 2573 return current; | 2625 return current; |
| 2574 } | 2626 } |
| 2575 current = current->next(); | 2627 current = current->next(); |
| 2576 } | 2628 } |
| 2577 return NULL; | 2629 return NULL; |
| 2578 } | 2630 } |
| 2579 | 2631 |
| 2580 } // namespace dart | 2632 } // namespace dart |
| OLD | NEW |