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

Side by Side Diff: runtime/vm/service.cc

Issue 2273463002: vm-service: Reduce copying involved in sending binary events (e.g., heap snapshot). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 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
« no previous file with comments | « runtime/vm/service.h ('k') | no next file » | 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 "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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698