| Index: runtime/vm/service.cc
|
| diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
|
| index ba3effa51f934bbf7250346d7adf8d447ec49232..d29a658cb8ef19ce4523a3a58efa5dff3b43e29d 100644
|
| --- a/runtime/vm/service.cc
|
| +++ b/runtime/vm/service.cc
|
| @@ -966,69 +966,86 @@ void Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) {
|
| }
|
|
|
|
|
| +static void Finalizer(void* isolate_callback_data,
|
| + Dart_WeakPersistentHandle handle,
|
| + void* buffer) {
|
| + free(buffer);
|
| +}
|
| +
|
| +
|
| void Service::SendEvent(const char* stream_id,
|
| const char* event_type,
|
| - const Object& event_message) {
|
| + uint8_t* bytes,
|
| + intptr_t bytes_length) {
|
| Thread* thread = Thread::Current();
|
| Isolate* isolate = thread->isolate();
|
| ASSERT(isolate != NULL);
|
| ASSERT(!ServiceIsolate::IsServiceIsolateDescendant(isolate));
|
| - if (!ServiceIsolate::IsRunning()) {
|
| - return;
|
| - }
|
| - HANDLESCOPE(thread);
|
| -
|
| - const Array& list = Array::Handle(Array::New(2));
|
| - ASSERT(!list.IsNull());
|
| - const String& stream_id_str = String::Handle(String::New(stream_id));
|
| - list.SetAt(0, stream_id_str);
|
| - list.SetAt(1, event_message);
|
|
|
| - // Push the event to port_.
|
| - uint8_t* data = NULL;
|
| - MessageWriter writer(&data, &allocator, false);
|
| - writer.WriteMessage(list);
|
| - intptr_t len = writer.BytesWritten();
|
| if (FLAG_trace_service) {
|
| OS::Print("vm-service: Pushing ServiceEvent(isolate='%s', kind='%s',"
|
| " len=%" Pd ") to stream %s\n",
|
| - isolate->name(), event_type, len, stream_id);
|
| + isolate->name(), event_type, bytes_length, stream_id);
|
| + }
|
| +
|
| + bool result;
|
| + {
|
| + TransitionVMToNative transition(thread);
|
| + Dart_CObject cbytes;
|
| + cbytes.type = Dart_CObject_kExternalTypedData;
|
| + cbytes.value.as_external_typed_data.type = Dart_TypedData_kUint8;
|
| + cbytes.value.as_external_typed_data.length = bytes_length;
|
| + cbytes.value.as_external_typed_data.data = bytes;
|
| + cbytes.value.as_external_typed_data.peer = bytes;
|
| + cbytes.value.as_external_typed_data.callback = Finalizer;
|
| +
|
| + Dart_CObject cstream_id;
|
| + cstream_id.type = Dart_CObject_kString;
|
| + cstream_id.value.as_string = const_cast<char*>(stream_id);
|
| +
|
| + Dart_CObject* elements[2];
|
| + elements[0] = &cstream_id;
|
| + elements[1] = &cbytes;
|
| + Dart_CObject message;
|
| + message.type = Dart_CObject_kArray;
|
| + message.value.as_array.length = 2;
|
| + message.value.as_array.values = elements;
|
| + result = Dart_PostCObject(ServiceIsolate::Port(), &message);
|
| + }
|
| +
|
| + if (!result) {
|
| + free(bytes);
|
| }
|
| - // TODO(turnidge): For now we ignore failure to send an event. Revisit?
|
| - PortMap::PostMessage(
|
| - new Message(ServiceIsolate::Port(), data, len, Message::kNormalPriority));
|
| }
|
|
|
|
|
| -// TODO(turnidge): Rewrite this method to use Post_CObject instead.
|
| void Service::SendEventWithData(const char* stream_id,
|
| const char* event_type,
|
| - const String& meta,
|
| + const char* metadata,
|
| + intptr_t metadata_size,
|
| const uint8_t* data,
|
| - intptr_t size) {
|
| - // Bitstream: [meta data size (big-endian 64 bit)] [meta data (UTF-8)] [data]
|
| - const intptr_t meta_bytes = Utf8::Length(meta);
|
| - const intptr_t total_bytes = sizeof(uint64_t) + meta_bytes + size;
|
| - const TypedData& message = TypedData::Handle(
|
| - TypedData::New(kTypedDataUint8ArrayCid, total_bytes));
|
| + intptr_t data_size) {
|
| + // Bitstream: [metadata size (big-endian 64 bit)] [metadata (UTF-8)] [data]
|
| + const intptr_t total_bytes = sizeof(uint64_t) + metadata_size + data_size;
|
| +
|
| + uint8_t* message = static_cast<uint8_t*>(malloc(total_bytes));
|
| intptr_t offset = 0;
|
| - // TODO(koda): Rename these methods SetHostUint64, etc.
|
| - message.SetUint64(0, Utils::HostToBigEndian64(meta_bytes));
|
| +
|
| + // Metadata size.
|
| + reinterpret_cast<uint64_t*>(message)[0] =
|
| + Utils::HostToBigEndian64(metadata_size);
|
| offset += sizeof(uint64_t);
|
| - {
|
| - NoSafepointScope no_safepoint;
|
| - meta.ToUTF8(static_cast<uint8_t*>(message.DataAddr(offset)), meta_bytes);
|
| - offset += meta_bytes;
|
| - }
|
| - // TODO(koda): It would be nice to avoid this copy (requires changes to
|
| - // MessageWriter code).
|
| - {
|
| - NoSafepointScope no_safepoint;
|
| - memmove(message.DataAddr(offset), data, size);
|
| - offset += size;
|
| - }
|
| +
|
| + // Metadata.
|
| + memmove(&message[offset], metadata, metadata_size);
|
| + offset += metadata_size;
|
| +
|
| + // Data.
|
| + memmove(&message[offset], data, data_size);
|
| + offset += data_size;
|
| +
|
| ASSERT(offset == total_bytes);
|
| - SendEvent(stream_id, event_type, message);
|
| + SendEvent(stream_id, event_type, message, total_bytes);
|
| }
|
|
|
|
|
| @@ -1409,9 +1426,10 @@ void Service::SendEchoEvent(Isolate* isolate, const char* text) {
|
| }
|
| }
|
| }
|
| - const String& message = String::Handle(String::New(js.ToCString()));
|
| uint8_t data[] = {0, 128, 255};
|
| - SendEventWithData(echo_stream.id(), "_Echo", message, data, sizeof(data));
|
| + SendEventWithData(echo_stream.id(), "_Echo",
|
| + js.buffer()->buf(), js.buffer()->length(),
|
| + data, sizeof(data));
|
| }
|
|
|
|
|
| @@ -3341,14 +3359,13 @@ void Service::SendGraphEvent(Thread* thread, bool collect_garbage) {
|
| }
|
| }
|
|
|
| - const String& message = String::Handle(String::New(js.ToCString()));
|
| -
|
| uint8_t* chunk_start = buffer + (i * kChunkSize);
|
| intptr_t chunk_size = (i + 1 == num_chunks)
|
| ? stream.bytes_written() - (i * kChunkSize)
|
| : kChunkSize;
|
|
|
| - SendEventWithData(graph_stream.id(), "_Graph", message,
|
| + SendEventWithData(graph_stream.id(), "_Graph",
|
| + js.buffer()->buf(), js.buffer()->length(),
|
| chunk_start, chunk_size);
|
| }
|
| }
|
|
|