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 "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 #include "platform/globals.h" | 9 #include "platform/globals.h" |
10 | 10 |
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 InvokeMethod(isolate, msg_instance, true); | 959 InvokeMethod(isolate, msg_instance, true); |
960 } | 960 } |
961 | 961 |
962 | 962 |
963 void Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) { | 963 void Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) { |
964 ASSERT(isolate != NULL); | 964 ASSERT(isolate != NULL); |
965 InvokeMethod(isolate, msg); | 965 InvokeMethod(isolate, msg); |
966 } | 966 } |
967 | 967 |
968 | 968 |
| 969 static void Finalizer(void* isolate_callback_data, |
| 970 Dart_WeakPersistentHandle handle, |
| 971 void* buffer) { |
| 972 free(buffer); |
| 973 } |
| 974 |
| 975 |
969 void Service::SendEvent(const char* stream_id, | 976 void Service::SendEvent(const char* stream_id, |
970 const char* event_type, | 977 const char* event_type, |
971 const Object& event_message) { | 978 uint8_t* bytes, |
| 979 intptr_t bytes_length) { |
972 Thread* thread = Thread::Current(); | 980 Thread* thread = Thread::Current(); |
973 Isolate* isolate = thread->isolate(); | 981 Isolate* isolate = thread->isolate(); |
974 ASSERT(isolate != NULL); | 982 ASSERT(isolate != NULL); |
975 ASSERT(!ServiceIsolate::IsServiceIsolateDescendant(isolate)); | 983 ASSERT(!ServiceIsolate::IsServiceIsolateDescendant(isolate)); |
976 if (!ServiceIsolate::IsRunning()) { | |
977 return; | |
978 } | |
979 HANDLESCOPE(thread); | |
980 | 984 |
981 const Array& list = Array::Handle(Array::New(2)); | |
982 ASSERT(!list.IsNull()); | |
983 const String& stream_id_str = String::Handle(String::New(stream_id)); | |
984 list.SetAt(0, stream_id_str); | |
985 list.SetAt(1, event_message); | |
986 | |
987 // Push the event to port_. | |
988 uint8_t* data = NULL; | |
989 MessageWriter writer(&data, &allocator, false); | |
990 writer.WriteMessage(list); | |
991 intptr_t len = writer.BytesWritten(); | |
992 if (FLAG_trace_service) { | 985 if (FLAG_trace_service) { |
993 OS::Print("vm-service: Pushing ServiceEvent(isolate='%s', kind='%s'," | 986 OS::Print("vm-service: Pushing ServiceEvent(isolate='%s', kind='%s'," |
994 " len=%" Pd ") to stream %s\n", | 987 " len=%" Pd ") to stream %s\n", |
995 isolate->name(), event_type, len, stream_id); | 988 isolate->name(), event_type, bytes_length, stream_id); |
996 } | 989 } |
997 // TODO(turnidge): For now we ignore failure to send an event. Revisit? | 990 |
998 PortMap::PostMessage( | 991 bool result; |
999 new Message(ServiceIsolate::Port(), data, len, Message::kNormalPriority)); | 992 { |
| 993 TransitionVMToNative transition(thread); |
| 994 Dart_CObject cbytes; |
| 995 cbytes.type = Dart_CObject_kExternalTypedData; |
| 996 cbytes.value.as_external_typed_data.type = Dart_TypedData_kUint8; |
| 997 cbytes.value.as_external_typed_data.length = bytes_length; |
| 998 cbytes.value.as_external_typed_data.data = bytes; |
| 999 cbytes.value.as_external_typed_data.peer = bytes; |
| 1000 cbytes.value.as_external_typed_data.callback = Finalizer; |
| 1001 |
| 1002 Dart_CObject cstream_id; |
| 1003 cstream_id.type = Dart_CObject_kString; |
| 1004 cstream_id.value.as_string = const_cast<char*>(stream_id); |
| 1005 |
| 1006 Dart_CObject* elements[2]; |
| 1007 elements[0] = &cstream_id; |
| 1008 elements[1] = &cbytes; |
| 1009 Dart_CObject message; |
| 1010 message.type = Dart_CObject_kArray; |
| 1011 message.value.as_array.length = 2; |
| 1012 message.value.as_array.values = elements; |
| 1013 result = Dart_PostCObject(ServiceIsolate::Port(), &message); |
| 1014 } |
| 1015 |
| 1016 if (!result) { |
| 1017 free(bytes); |
| 1018 } |
1000 } | 1019 } |
1001 | 1020 |
1002 | 1021 |
1003 // TODO(turnidge): Rewrite this method to use Post_CObject instead. | |
1004 void Service::SendEventWithData(const char* stream_id, | 1022 void Service::SendEventWithData(const char* stream_id, |
1005 const char* event_type, | 1023 const char* event_type, |
1006 const String& meta, | 1024 const char* metadata, |
| 1025 intptr_t metadata_size, |
1007 const uint8_t* data, | 1026 const uint8_t* data, |
1008 intptr_t size) { | 1027 intptr_t data_size) { |
1009 // Bitstream: [meta data size (big-endian 64 bit)] [meta data (UTF-8)] [data] | 1028 // Bitstream: [metadata size (big-endian 64 bit)] [metadata (UTF-8)] [data] |
1010 const intptr_t meta_bytes = Utf8::Length(meta); | 1029 const intptr_t total_bytes = sizeof(uint64_t) + metadata_size + data_size; |
1011 const intptr_t total_bytes = sizeof(uint64_t) + meta_bytes + size; | 1030 |
1012 const TypedData& message = TypedData::Handle( | 1031 uint8_t* message = static_cast<uint8_t*>(malloc(total_bytes)); |
1013 TypedData::New(kTypedDataUint8ArrayCid, total_bytes)); | |
1014 intptr_t offset = 0; | 1032 intptr_t offset = 0; |
1015 // TODO(koda): Rename these methods SetHostUint64, etc. | 1033 |
1016 message.SetUint64(0, Utils::HostToBigEndian64(meta_bytes)); | 1034 // Metadata size. |
| 1035 reinterpret_cast<uint64_t*>(message)[0] = |
| 1036 Utils::HostToBigEndian64(metadata_size); |
1017 offset += sizeof(uint64_t); | 1037 offset += sizeof(uint64_t); |
1018 { | 1038 |
1019 NoSafepointScope no_safepoint; | 1039 // Metadata. |
1020 meta.ToUTF8(static_cast<uint8_t*>(message.DataAddr(offset)), meta_bytes); | 1040 memmove(&message[offset], metadata, metadata_size); |
1021 offset += meta_bytes; | 1041 offset += metadata_size; |
1022 } | 1042 |
1023 // TODO(koda): It would be nice to avoid this copy (requires changes to | 1043 // Data. |
1024 // MessageWriter code). | 1044 memmove(&message[offset], data, data_size); |
1025 { | 1045 offset += data_size; |
1026 NoSafepointScope no_safepoint; | 1046 |
1027 memmove(message.DataAddr(offset), data, size); | |
1028 offset += size; | |
1029 } | |
1030 ASSERT(offset == total_bytes); | 1047 ASSERT(offset == total_bytes); |
1031 SendEvent(stream_id, event_type, message); | 1048 SendEvent(stream_id, event_type, message, total_bytes); |
1032 } | 1049 } |
1033 | 1050 |
1034 | 1051 |
1035 static void ReportPauseOnConsole(ServiceEvent* event) { | 1052 static void ReportPauseOnConsole(ServiceEvent* event) { |
1036 const char* name = event->isolate()->debugger_name(); | 1053 const char* name = event->isolate()->debugger_name(); |
1037 switch (event->kind()) { | 1054 switch (event->kind()) { |
1038 case ServiceEvent::kPauseStart: | 1055 case ServiceEvent::kPauseStart: |
1039 OS::PrintErr( | 1056 OS::PrintErr( |
1040 "vm-service: isolate '%s' has no debugger attached and is paused at " | 1057 "vm-service: isolate '%s' has no debugger attached and is paused at " |
1041 "start.", name); | 1058 "start.", name); |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1402 event.AddProperty("type", "Event"); | 1419 event.AddProperty("type", "Event"); |
1403 event.AddProperty("kind", "_Echo"); | 1420 event.AddProperty("kind", "_Echo"); |
1404 event.AddProperty("isolate", isolate); | 1421 event.AddProperty("isolate", isolate); |
1405 if (text != NULL) { | 1422 if (text != NULL) { |
1406 event.AddProperty("text", text); | 1423 event.AddProperty("text", text); |
1407 } | 1424 } |
1408 event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis()); | 1425 event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis()); |
1409 } | 1426 } |
1410 } | 1427 } |
1411 } | 1428 } |
1412 const String& message = String::Handle(String::New(js.ToCString())); | |
1413 uint8_t data[] = {0, 128, 255}; | 1429 uint8_t data[] = {0, 128, 255}; |
1414 SendEventWithData(echo_stream.id(), "_Echo", message, data, sizeof(data)); | 1430 SendEventWithData(echo_stream.id(), "_Echo", |
| 1431 js.buffer()->buf(), js.buffer()->length(), |
| 1432 data, sizeof(data)); |
1415 } | 1433 } |
1416 | 1434 |
1417 | 1435 |
1418 static bool TriggerEchoEvent(Thread* thread, JSONStream* js) { | 1436 static bool TriggerEchoEvent(Thread* thread, JSONStream* js) { |
1419 if (Service::echo_stream.enabled()) { | 1437 if (Service::echo_stream.enabled()) { |
1420 Service::SendEchoEvent(thread->isolate(), js->LookupParam("text")); | 1438 Service::SendEchoEvent(thread->isolate(), js->LookupParam("text")); |
1421 } | 1439 } |
1422 JSONObject jsobj(js); | 1440 JSONObject jsobj(js); |
1423 return HandleCommonEcho(&jsobj, js); | 1441 return HandleCommonEcho(&jsobj, js); |
1424 } | 1442 } |
(...skipping 1909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3334 event.AddProperty("isolate", thread->isolate()); | 3352 event.AddProperty("isolate", thread->isolate()); |
3335 event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis()); | 3353 event.AddPropertyTimeMillis("timestamp", OS::GetCurrentTimeMillis()); |
3336 | 3354 |
3337 event.AddProperty("chunkIndex", i); | 3355 event.AddProperty("chunkIndex", i); |
3338 event.AddProperty("chunkCount", num_chunks); | 3356 event.AddProperty("chunkCount", num_chunks); |
3339 event.AddProperty("nodeCount", node_count); | 3357 event.AddProperty("nodeCount", node_count); |
3340 } | 3358 } |
3341 } | 3359 } |
3342 } | 3360 } |
3343 | 3361 |
3344 const String& message = String::Handle(String::New(js.ToCString())); | |
3345 | |
3346 uint8_t* chunk_start = buffer + (i * kChunkSize); | 3362 uint8_t* chunk_start = buffer + (i * kChunkSize); |
3347 intptr_t chunk_size = (i + 1 == num_chunks) | 3363 intptr_t chunk_size = (i + 1 == num_chunks) |
3348 ? stream.bytes_written() - (i * kChunkSize) | 3364 ? stream.bytes_written() - (i * kChunkSize) |
3349 : kChunkSize; | 3365 : kChunkSize; |
3350 | 3366 |
3351 SendEventWithData(graph_stream.id(), "_Graph", message, | 3367 SendEventWithData(graph_stream.id(), "_Graph", |
| 3368 js.buffer()->buf(), js.buffer()->length(), |
3352 chunk_start, chunk_size); | 3369 chunk_start, chunk_size); |
3353 } | 3370 } |
3354 } | 3371 } |
3355 | 3372 |
3356 | 3373 |
3357 void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) { | 3374 void Service::SendInspectEvent(Isolate* isolate, const Object& inspectee) { |
3358 if (!Service::debug_stream.enabled()) { | 3375 if (!Service::debug_stream.enabled()) { |
3359 return; | 3376 return; |
3360 } | 3377 } |
3361 ServiceEvent event(isolate, ServiceEvent::kInspect); | 3378 ServiceEvent event(isolate, ServiceEvent::kInspect); |
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4147 if (strcmp(method_name, method.name) == 0) { | 4164 if (strcmp(method_name, method.name) == 0) { |
4148 return &method; | 4165 return &method; |
4149 } | 4166 } |
4150 } | 4167 } |
4151 return NULL; | 4168 return NULL; |
4152 } | 4169 } |
4153 | 4170 |
4154 #endif // !PRODUCT | 4171 #endif // !PRODUCT |
4155 | 4172 |
4156 } // namespace dart | 4173 } // namespace dart |
OLD | NEW |