Chromium Code Reviews| 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", "_echo/event"); | |
| 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/isolate"); |
| 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 1463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2270 js.PostReply(); | 2296 js.PostReply(); |
| 2271 } | 2297 } |
| 2272 } | 2298 } |
| 2273 } | 2299 } |
| 2274 } | 2300 } |
| 2275 } | 2301 } |
| 2276 | 2302 |
| 2277 | 2303 |
| 2278 static bool HandleRootEcho(JSONStream* js) { | 2304 static bool HandleRootEcho(JSONStream* js) { |
| 2279 JSONObject jsobj(js); | 2305 JSONObject jsobj(js); |
| 2280 jsobj.AddProperty("type", "message"); | 2306 jsobj.AddProperty("id", "_echo/root"); |
| 2281 PrintArgumentsAndOptions(jsobj, js); | 2307 return HandleCommonEcho(&jsobj, js); |
| 2282 return true; | |
| 2283 } | 2308 } |
| 2284 | 2309 |
| 2285 | 2310 |
| 2286 class ServiceIsolateVisitor : public IsolateVisitor { | 2311 class ServiceIsolateVisitor : public IsolateVisitor { |
| 2287 public: | 2312 public: |
| 2288 explicit ServiceIsolateVisitor(JSONArray* jsarr) | 2313 explicit ServiceIsolateVisitor(JSONArray* jsarr) |
| 2289 : jsarr_(jsarr) { | 2314 : jsarr_(jsarr) { |
| 2290 } | 2315 } |
| 2291 | 2316 |
| 2292 virtual ~ServiceIsolateVisitor() {} | 2317 virtual ~ServiceIsolateVisitor() {} |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2385 return entry.handler; | 2410 return entry.handler; |
| 2386 } | 2411 } |
| 2387 } | 2412 } |
| 2388 if (FLAG_trace_service) { | 2413 if (FLAG_trace_service) { |
| 2389 OS::Print("Service has no root message handler for <%s>\n", command); | 2414 OS::Print("Service has no root message handler for <%s>\n", command); |
| 2390 } | 2415 } |
| 2391 return NULL; | 2416 return NULL; |
| 2392 } | 2417 } |
| 2393 | 2418 |
| 2394 | 2419 |
| 2395 void Service::SendEvent(intptr_t eventId, const String& eventMessage) { | 2420 void Service::SendEvent(intptr_t eventId, const Object& eventMessage) { |
| 2396 if (!IsRunning()) { | 2421 if (!IsRunning()) { |
| 2397 return; | 2422 return; |
| 2398 } | 2423 } |
| 2399 Isolate* isolate = Isolate::Current(); | 2424 Isolate* isolate = Isolate::Current(); |
| 2400 ASSERT(isolate != NULL); | 2425 ASSERT(isolate != NULL); |
| 2401 HANDLESCOPE(isolate); | 2426 HANDLESCOPE(isolate); |
| 2402 | 2427 |
| 2403 // Construct a list of the form [eventId, eventMessage]. | 2428 // Construct a list of the form [eventId, eventMessage]. |
| 2404 const Array& list = Array::Handle(Array::New(2)); | 2429 const Array& list = Array::Handle(Array::New(2)); |
| 2405 ASSERT(!list.IsNull()); | 2430 ASSERT(!list.IsNull()); |
| 2406 list.SetAt(0, Integer::Handle(Integer::New(eventId))); | 2431 list.SetAt(0, Integer::Handle(Integer::New(eventId))); |
| 2407 list.SetAt(1, eventMessage); | 2432 list.SetAt(1, eventMessage); |
| 2408 | 2433 |
| 2409 // Push the event to port_. | 2434 // Push the event to port_. |
| 2410 uint8_t* data = NULL; | 2435 uint8_t* data = NULL; |
| 2411 MessageWriter writer(&data, &allocator); | 2436 MessageWriter writer(&data, &allocator); |
| 2412 writer.WriteMessage(list); | 2437 writer.WriteMessage(list); |
| 2413 intptr_t len = writer.BytesWritten(); | 2438 intptr_t len = writer.BytesWritten(); |
| 2414 if (FLAG_trace_service) { | 2439 if (FLAG_trace_service) { |
| 2415 OS::Print("Pushing event of type %" Pd ", len %" Pd "\n", eventId, len); | 2440 OS::Print("Pushing event of type %" Pd ", len %" Pd "\n", eventId, len); |
| 2416 } | 2441 } |
| 2417 // TODO(turnidge): For now we ignore failure to send an event. Revisit? | 2442 // TODO(turnidge): For now we ignore failure to send an event. Revisit? |
| 2418 PortMap::PostMessage( | 2443 PortMap::PostMessage( |
| 2419 new Message(port_, data, len, Message::kNormalPriority)); | 2444 new Message(port_, data, len, Message::kNormalPriority)); |
| 2420 } | 2445 } |
| 2421 | 2446 |
| 2422 | 2447 |
| 2448 void Service::SendEvent(intptr_t eventId, | |
| 2449 const String& meta, | |
| 2450 const uint8_t* data, | |
| 2451 intptr_t size) { | |
| 2452 // Bitstream: [meta data size (big-endian 64 bit)] [meta data (UTF-8)] [data] | |
| 2453 const intptr_t meta_bytes = Utf8::Length(meta); | |
| 2454 const intptr_t total_bytes = sizeof(uint64_t) + meta_bytes + size; | |
|
Cutch
2014/08/15 21:33:58
Do we really need 64-bits to encode the meta-data
koda
2014/08/15 22:20:53
Do we really need more than 32 bits for IP address
| |
| 2455 const TypedData& message = TypedData::Handle( | |
| 2456 TypedData::New(kTypedDataUint8ArrayCid, total_bytes)); | |
| 2457 intptr_t offset = 0; | |
| 2458 // TODO(koda): Rename these methods SetHostUint64, etc. | |
| 2459 message.SetUint64(0, Utils::HostToBigEndian64(meta_bytes)); | |
| 2460 offset += sizeof(uint64_t); | |
| 2461 { | |
| 2462 NoGCScope no_gc; | |
| 2463 meta.ToUTF8(static_cast<uint8_t*>(message.DataAddr(offset)), meta_bytes); | |
| 2464 offset += meta_bytes; | |
| 2465 } | |
| 2466 memmove(message.DataAddr(offset), data, size); | |
| 2467 offset += size; | |
| 2468 ASSERT(offset == total_bytes); | |
| 2469 SendEvent(eventId, message); | |
| 2470 } | |
| 2471 | |
| 2472 | |
| 2423 void Service::HandleGCEvent(GCEvent* event) { | 2473 void Service::HandleGCEvent(GCEvent* event) { |
| 2424 JSONStream js; | 2474 JSONStream js; |
| 2425 event->PrintJSON(&js); | 2475 event->PrintJSON(&js); |
| 2426 const String& message = String::Handle(String::New(js.ToCString())); | 2476 const String& message = String::Handle(String::New(js.ToCString())); |
| 2427 SendEvent(kEventFamilyGC, message); | 2477 SendEvent(kEventFamilyGC, message); |
| 2428 } | 2478 } |
| 2429 | 2479 |
| 2430 | 2480 |
| 2431 void Service::HandleDebuggerEvent(DebuggerEvent* event) { | 2481 void Service::HandleDebuggerEvent(DebuggerEvent* event) { |
| 2432 JSONStream js; | 2482 JSONStream js; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2525 while (current != NULL) { | 2575 while (current != NULL) { |
| 2526 if (strcmp(name, current->name()) == 0) { | 2576 if (strcmp(name, current->name()) == 0) { |
| 2527 return current; | 2577 return current; |
| 2528 } | 2578 } |
| 2529 current = current->next(); | 2579 current = current->next(); |
| 2530 } | 2580 } |
| 2531 return NULL; | 2581 return NULL; |
| 2532 } | 2582 } |
| 2533 | 2583 |
| 2534 } // namespace dart | 2584 } // namespace dart |
| OLD | NEW |