mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Reduce copying in sending service responses.
Add missing safepoint transitions. Issue #27092 Likely contributes to Issue #27010 dart2js hello Peak RSS at first Observatory visit -> Peak RSS after visiting timeline (with endless recorder) Before 215M -> 321M After 182M -> 233M R=johnmccutchan@google.com Review URL: https://codereview.chromium.org/2254543006 .
This commit is contained in:
parent
bfa70e6df2
commit
d418dde65b
|
@ -51,7 +51,17 @@ class WebSocketClient extends Client {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
socket.add(result);
|
||||
if (result is String || result is Uint8List) {
|
||||
socket.add(result); // String or binary message.
|
||||
} else {
|
||||
// String message as external Uint8List.
|
||||
assert(result is List);
|
||||
Uint8List cstring = result[0];
|
||||
// TODO(rmacnak): cstring may be large. Add a way to pass an encoded
|
||||
// string to a web socket that will be sent as a text message to avoid
|
||||
// the space overhead of converting cstring to a Dart string.
|
||||
socket.add(UTF8.decode(cstring));
|
||||
}
|
||||
} catch (_) {
|
||||
print("Ignoring error posting over WebSocket.");
|
||||
}
|
||||
|
@ -79,14 +89,21 @@ class HttpRequestClient extends Client {
|
|||
close();
|
||||
}
|
||||
|
||||
void post(String result) {
|
||||
void post(dynamic result) {
|
||||
if (result == null) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
request.response..headers.contentType = jsonContentType
|
||||
..write(result)
|
||||
..close();
|
||||
HttpResponse response = request.response;
|
||||
response.headers.contentType = jsonContentType;
|
||||
if (result is String) {
|
||||
response.write(result);
|
||||
} else {
|
||||
assert(result is List);
|
||||
Uint8List cstring = result[0]; // Already in UTF-8.
|
||||
response.add(cstring);
|
||||
}
|
||||
response.close();
|
||||
close();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'dart:collection';
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:_vmservice';
|
||||
|
||||
part 'loader.dart';
|
||||
|
|
|
@ -32,8 +32,8 @@ void TextBuffer::Clear() {
|
|||
}
|
||||
|
||||
|
||||
const char* TextBuffer::Steal() {
|
||||
const char* r = buf_;
|
||||
char* TextBuffer::Steal() {
|
||||
char* r = buf_;
|
||||
buf_ = NULL;
|
||||
buf_size_ = 0;
|
||||
msg_len_ = 0;
|
||||
|
|
|
@ -34,7 +34,7 @@ class TextBuffer : ValueObject {
|
|||
|
||||
// Steal ownership of the buffer pointer.
|
||||
// NOTE: TextBuffer is empty afterwards.
|
||||
const char* Steal();
|
||||
char* Steal();
|
||||
|
||||
private:
|
||||
void EnsureCapacity(intptr_t len);
|
||||
|
|
|
@ -6127,7 +6127,7 @@ static bool StreamTraceEvents(Dart_StreamConsumer consumer,
|
|||
// Steal output from JSONStream.
|
||||
char* output = NULL;
|
||||
intptr_t output_length = 0;
|
||||
js->Steal(const_cast<const char**>(&output), &output_length);
|
||||
js->Steal(&output, &output_length);
|
||||
if (output_length < 3) {
|
||||
// Empty JSON array.
|
||||
free(output);
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
|
||||
#include "platform/assert.h"
|
||||
|
||||
#include "include/dart_native_api.h"
|
||||
#include "vm/dart_entry.h"
|
||||
#include "vm/debugger.h"
|
||||
#include "vm/json_stream.h"
|
||||
#include "vm/message.h"
|
||||
#include "vm/metrics.h"
|
||||
#include "vm/object.h"
|
||||
#include "vm/safepoint.h"
|
||||
#include "vm/service.h"
|
||||
#include "vm/service_event.h"
|
||||
#include "vm/timeline.h"
|
||||
|
@ -193,18 +195,19 @@ void JSONStream::PrintError(intptr_t code,
|
|||
}
|
||||
|
||||
|
||||
static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
|
||||
void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
|
||||
return reinterpret_cast<uint8_t*>(new_ptr);
|
||||
}
|
||||
|
||||
|
||||
void JSONStream::PostNullReply(Dart_Port port) {
|
||||
PortMap::PostMessage(new Message(
|
||||
port, Object::null(), Message::kNormalPriority));
|
||||
}
|
||||
|
||||
|
||||
static void Finalizer(void* isolate_callback_data,
|
||||
Dart_WeakPersistentHandle handle,
|
||||
void* buffer) {
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
void JSONStream::PostReply() {
|
||||
Dart_Port port = reply_port();
|
||||
ASSERT(port != ILLEGAL_PORT);
|
||||
|
@ -226,15 +229,33 @@ void JSONStream::PostReply() {
|
|||
}
|
||||
buffer_.AddChar('}');
|
||||
|
||||
const String& reply = String::Handle(String::New(ToCString()));
|
||||
ASSERT(!reply.IsNull());
|
||||
char* cstr;
|
||||
intptr_t length;
|
||||
Steal(&cstr, &length);
|
||||
|
||||
bool result;
|
||||
{
|
||||
TransitionVMToNative transition(Thread::Current());
|
||||
Dart_CObject bytes;
|
||||
bytes.type = Dart_CObject_kExternalTypedData;
|
||||
bytes.value.as_external_typed_data.type = Dart_TypedData_kUint8;
|
||||
bytes.value.as_external_typed_data.length = length;
|
||||
bytes.value.as_external_typed_data.data = reinterpret_cast<uint8_t*>(cstr);
|
||||
bytes.value.as_external_typed_data.peer = cstr;
|
||||
bytes.value.as_external_typed_data.callback = Finalizer;
|
||||
Dart_CObject* elements[1];
|
||||
elements[0] = &bytes;
|
||||
Dart_CObject message;
|
||||
message.type = Dart_CObject_kArray;
|
||||
message.value.as_array.length = 1;
|
||||
message.value.as_array.values = elements;
|
||||
result = Dart_PostCObject(port, &message);
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
free(cstr);
|
||||
}
|
||||
|
||||
uint8_t* data = NULL;
|
||||
MessageWriter writer(&data, &allocator, false);
|
||||
writer.WriteMessage(reply);
|
||||
bool result = PortMap::PostMessage(new Message(port, data,
|
||||
writer.BytesWritten(),
|
||||
Message::kNormalPriority));
|
||||
if (FLAG_trace_service) {
|
||||
Isolate* isolate = Isolate::Current();
|
||||
ASSERT(isolate != NULL);
|
||||
|
@ -672,7 +693,7 @@ void JSONStream::PrintfProperty(const char* name, const char* format, ...) {
|
|||
}
|
||||
|
||||
|
||||
void JSONStream::Steal(const char** buffer, intptr_t* buffer_length) {
|
||||
void JSONStream::Steal(char** buffer, intptr_t* buffer_length) {
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT(buffer_length != NULL);
|
||||
*buffer_length = buffer_.length();
|
||||
|
|
|
@ -97,7 +97,7 @@ class JSONStream : ValueObject {
|
|||
TextBuffer* buffer() { return &buffer_; }
|
||||
const char* ToCString() { return buffer_.buf(); }
|
||||
|
||||
void Steal(const char** buffer, intptr_t* buffer_length);
|
||||
void Steal(char** buffer, intptr_t* buffer_length);
|
||||
|
||||
void set_reply_port(Dart_Port port);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "vm/port.h"
|
||||
#include "vm/profiler_service.h"
|
||||
#include "vm/reusable_handles.h"
|
||||
#include "vm/safepoint.h"
|
||||
#include "vm/service_event.h"
|
||||
#include "vm/service_isolate.h"
|
||||
#include "vm/source_report.h"
|
||||
|
@ -838,6 +839,7 @@ void Service::InvokeMethod(Isolate* I,
|
|||
Thread* T = Thread::Current();
|
||||
ASSERT(I == T->isolate());
|
||||
ASSERT(I != NULL);
|
||||
ASSERT(T->execution_state() == Thread::kThreadInVM);
|
||||
ASSERT(!msg.IsNull());
|
||||
ASSERT(msg.Length() == 6);
|
||||
|
||||
|
@ -1195,8 +1197,12 @@ void Service::EmbedderHandleMessage(EmbedderServiceHandler* handler,
|
|||
Dart_ServiceRequestCallback callback = handler->callback();
|
||||
ASSERT(callback != NULL);
|
||||
const char* response = NULL;
|
||||
bool success = callback(js->method(), js->param_keys(), js->param_values(),
|
||||
js->num_params(), handler->user_data(), &response);
|
||||
bool success;
|
||||
{
|
||||
TransitionVMToNative transition(Thread::Current());
|
||||
success = callback(js->method(), js->param_keys(), js->param_values(),
|
||||
js->num_params(), handler->user_data(), &response);
|
||||
}
|
||||
ASSERT(response != NULL);
|
||||
if (!success) {
|
||||
js->SetupError();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "vm/object_id_ring.h"
|
||||
#include "vm/os.h"
|
||||
#include "vm/port.h"
|
||||
#include "vm/safepoint.h"
|
||||
#include "vm/service.h"
|
||||
#include "vm/unit_test.h"
|
||||
|
||||
|
@ -37,7 +38,6 @@ class ServiceTestMessageHandler : public MessageHandler {
|
|||
}
|
||||
|
||||
// Parse the message.
|
||||
String& response = String::Handle();
|
||||
Object& response_obj = Object::Handle();
|
||||
if (message->IsRaw()) {
|
||||
response_obj = message->raw_obj();
|
||||
|
@ -46,8 +46,20 @@ class ServiceTestMessageHandler : public MessageHandler {
|
|||
MessageSnapshotReader reader(message->data(), message->len(), thread);
|
||||
response_obj = reader.ReadObject();
|
||||
}
|
||||
response ^= response_obj.raw();
|
||||
_msg = strdup(response.ToCString());
|
||||
if (response_obj.IsString()) {
|
||||
String& response = String::Handle();
|
||||
response ^= response_obj.raw();
|
||||
_msg = strdup(response.ToCString());
|
||||
} else {
|
||||
ASSERT(response_obj.IsArray());
|
||||
Array& response_array = Array::Handle();
|
||||
response_array ^= response_obj.raw();
|
||||
ASSERT(response_array.Length() == 1);
|
||||
ExternalTypedData& response = ExternalTypedData::Handle();
|
||||
response ^= response_array.At(0);
|
||||
_msg = strdup(reinterpret_cast<char*>(response.DataAddr(0)));
|
||||
}
|
||||
|
||||
return kOK;
|
||||
}
|
||||
|
||||
|
@ -115,6 +127,18 @@ static RawClass* GetClass(const Library& lib, const char* name) {
|
|||
}
|
||||
|
||||
|
||||
static void HandleIsolateMessage(Isolate* isolate, const Array& msg) {
|
||||
TransitionNativeToVM transition(Thread::Current());
|
||||
Service::HandleIsolateMessage(isolate, msg);
|
||||
}
|
||||
|
||||
|
||||
static void HandleRootMessage(const Array& message) {
|
||||
TransitionNativeToVM transition(Thread::Current());
|
||||
Service::HandleRootMessage(message);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(Service_IsolateStickyError) {
|
||||
const char* kScript =
|
||||
"main() => throw 'HI THERE STICKY';\n";
|
||||
|
@ -245,7 +269,7 @@ TEST_CASE(Service_Code) {
|
|||
// Request an invalid code object.
|
||||
service_msg =
|
||||
Eval(lib, "[0, port, '0', 'getObject', ['objectId'], ['code/0']]");
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_SUBSTRING("\"error\"", handler.msg());
|
||||
|
||||
|
@ -255,7 +279,7 @@ TEST_CASE(Service_Code) {
|
|||
"['objectId'], ['code/%" Px64"-%" Px "']]",
|
||||
compile_timestamp,
|
||||
entry);
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_SUBSTRING("\"type\":\"Code\"", handler.msg());
|
||||
{
|
||||
|
@ -276,7 +300,7 @@ TEST_CASE(Service_Code) {
|
|||
"['objectId'], ['code/%" Px64"-%" Px "']]",
|
||||
compile_timestamp,
|
||||
address);
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_SUBSTRING("\"error\"", handler.msg());
|
||||
|
||||
|
@ -287,7 +311,7 @@ TEST_CASE(Service_Code) {
|
|||
"['objectId'], ['code/%" Px64"-%" Px "']]",
|
||||
compile_timestamp - 1,
|
||||
address);
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_SUBSTRING("\"error\"", handler.msg());
|
||||
|
||||
|
@ -296,7 +320,7 @@ TEST_CASE(Service_Code) {
|
|||
service_msg = EvalF(lib, "[0, port, '0', 'getObject', "
|
||||
"['objectId'], ['code/native-%" Px "']]",
|
||||
address);
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
// TODO(turnidge): It is pretty broken to return an Instance here. Fix.
|
||||
EXPECT_SUBSTRING("\"kind\":\"Null\"",
|
||||
|
@ -306,7 +330,7 @@ TEST_CASE(Service_Code) {
|
|||
service_msg = EvalF(lib, "[0, port, '0', 'getObject', ['objectId'], "
|
||||
"['code/native%" Px "']]",
|
||||
address);
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_SUBSTRING("\"error\"", handler.msg());
|
||||
}
|
||||
|
@ -349,7 +373,7 @@ TEST_CASE(Service_TokenStream) {
|
|||
// Fetch object.
|
||||
service_msg = EvalF(lib, "[0, port, '0', 'getObject', "
|
||||
"['objectId'], ['objects/%" Pd "']]", id);
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
|
||||
// Check type.
|
||||
|
@ -412,7 +436,7 @@ TEST_CASE(Service_PcDescriptors) {
|
|||
// Fetch object.
|
||||
service_msg = EvalF(lib, "[0, port, '0', 'getObject', "
|
||||
"['objectId'], ['objects/%" Pd "']]", id);
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
// Check type.
|
||||
EXPECT_SUBSTRING("\"type\":\"Object\"", handler.msg());
|
||||
|
@ -474,7 +498,7 @@ TEST_CASE(Service_LocalVarDescriptors) {
|
|||
// Fetch object.
|
||||
service_msg = EvalF(lib, "[0, port, '0', 'getObject', "
|
||||
"['objectId'], ['objects/%" Pd "']]", id);
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
// Check type.
|
||||
EXPECT_SUBSTRING("\"type\":\"Object\"", handler.msg());
|
||||
|
@ -534,7 +558,7 @@ TEST_CASE(Service_PersistentHandles) {
|
|||
|
||||
// Get persistent handles.
|
||||
service_msg = Eval(lib, "[0, port, '0', '_getPersistentHandles', [], []]");
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
// Look for a heart beat.
|
||||
EXPECT_SUBSTRING("\"type\":\"_PersistentHandles\"", handler.msg());
|
||||
|
@ -549,7 +573,7 @@ TEST_CASE(Service_PersistentHandles) {
|
|||
|
||||
// Get persistent handles (again).
|
||||
service_msg = Eval(lib, "[0, port, '0', '_getPersistentHandles', [], []]");
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_SUBSTRING("\"type\":\"_PersistentHandles\"", handler.msg());
|
||||
// Verify that old persistent handles are not present.
|
||||
|
@ -595,7 +619,7 @@ TEST_CASE(Service_Address) {
|
|||
"['address'], ['%" Px "']]"),
|
||||
addr);
|
||||
service_msg = Eval(lib, buf);
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_SUBSTRING(ref ? "\"type\":\"@Instance\"" :
|
||||
"\"type\":\"Instance\"",
|
||||
|
@ -606,7 +630,7 @@ TEST_CASE(Service_Address) {
|
|||
// Expect null when no object is found.
|
||||
service_msg = Eval(lib, "[0, port, '0', '_getObjectByAddress', "
|
||||
"['address'], ['7']]");
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
// TODO(turnidge): Should this be a ServiceException instead?
|
||||
EXPECT_SUBSTRING("{\"type\":\"Sentinel\",\"kind\":\"Free\","
|
||||
|
@ -667,12 +691,12 @@ TEST_CASE(Service_EmbedderRootHandler) {
|
|||
|
||||
Array& service_msg = Array::Handle();
|
||||
service_msg = Eval(lib, "[0, port, '\"', 'alpha', [], []]");
|
||||
Service::HandleRootMessage(service_msg);
|
||||
HandleRootMessage(service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"result\":alpha,\"id\":\"\\\"\"}",
|
||||
handler.msg());
|
||||
service_msg = Eval(lib, "[0, port, 1, 'beta', [], []]");
|
||||
Service::HandleRootMessage(service_msg);
|
||||
HandleRootMessage(service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"error\":beta,\"id\":1}",
|
||||
handler.msg());
|
||||
|
@ -707,12 +731,12 @@ TEST_CASE(Service_EmbedderIsolateHandler) {
|
|||
|
||||
Array& service_msg = Array::Handle();
|
||||
service_msg = Eval(lib, "[0, port, '0', 'alpha', [], []]");
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"result\":alpha,\"id\":\"0\"}",
|
||||
handler.msg());
|
||||
service_msg = Eval(lib, "[0, port, '0', 'beta', [], []]");
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"error\":beta,\"id\":\"0\"}",
|
||||
handler.msg());
|
||||
|
@ -747,21 +771,21 @@ TEST_CASE(Service_Profile) {
|
|||
|
||||
Array& service_msg = Array::Handle();
|
||||
service_msg = Eval(lib, "[0, port, '0', '_getCpuProfile', [], []]");
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
// Expect error (tags required).
|
||||
EXPECT_SUBSTRING("\"error\"", handler.msg());
|
||||
|
||||
service_msg =
|
||||
Eval(lib, "[0, port, '0', '_getCpuProfile', ['tags'], ['None']]");
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
// Expect profile
|
||||
EXPECT_SUBSTRING("\"type\":\"_CpuProfile\"", handler.msg());
|
||||
|
||||
service_msg =
|
||||
Eval(lib, "[0, port, '0', '_getCpuProfile', ['tags'], ['Bogus']]");
|
||||
Service::HandleIsolateMessage(isolate, service_msg);
|
||||
HandleIsolateMessage(isolate, service_msg);
|
||||
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
|
||||
// Expect error.
|
||||
EXPECT_SUBSTRING("\"error\"", handler.msg());
|
||||
|
|
|
@ -1180,7 +1180,7 @@ void TimelineEventRecorder::WriteTo(const char* directory) {
|
|||
// Steal output from JSONStream.
|
||||
char* output = NULL;
|
||||
intptr_t output_length = 0;
|
||||
js.Steal(const_cast<const char**>(&output), &output_length);
|
||||
js.Steal(&output, &output_length);
|
||||
(*file_write)(output, output_length, file);
|
||||
// Free the stolen output.
|
||||
free(output);
|
||||
|
|
|
@ -330,6 +330,15 @@ class VMService extends MessageRouter {
|
|||
return encodeSuccess(message);
|
||||
}
|
||||
|
||||
static responseAsJson(portResponse) {
|
||||
if (portResponse is String) {
|
||||
return JSON.decode(portResponse);
|
||||
} else {
|
||||
var cstring = portResponse[0];
|
||||
return JSON.fuse(UTF8).decode(cstring);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(johnmccutchan): Turn this into a command line tool that uses the
|
||||
// service library.
|
||||
Future<String> _getCrashDump(Message message) async {
|
||||
|
@ -353,13 +362,13 @@ class VMService extends MessageRouter {
|
|||
|
||||
// Request VM.
|
||||
var getVM = Uri.parse('getVM');
|
||||
var getVmResponse = JSON.decode(
|
||||
var getVmResponse = responseAsJson(
|
||||
await new Message.fromUri(client, getVM).sendToVM());
|
||||
responses[getVM.toString()] = getVmResponse['result'];
|
||||
|
||||
// Request command line flags.
|
||||
var getFlagList = Uri.parse('getFlagList');
|
||||
var getFlagListResponse = JSON.decode(
|
||||
var getFlagListResponse = responseAsJson(
|
||||
await new Message.fromUri(client, getFlagList).sendToVM());
|
||||
responses[getFlagList.toString()] = getFlagListResponse['result'];
|
||||
|
||||
|
@ -369,13 +378,13 @@ class VMService extends MessageRouter {
|
|||
var message = new Message.forIsolate(client, request, isolate);
|
||||
// Decode the JSON and and insert it into the map. The map key
|
||||
// is the request Uri.
|
||||
var response = JSON.decode(await isolate.route(message));
|
||||
var response = responseAsJson(await isolate.route(message));
|
||||
responses[message.toUri().toString()] = response['result'];
|
||||
}
|
||||
// Dump the object id ring requests.
|
||||
var message =
|
||||
new Message.forIsolate(client, Uri.parse('_dumpIdZone'), isolate);
|
||||
var response = JSON.decode(await isolate.route(message));
|
||||
var response = responseAsJson(await isolate.route(message));
|
||||
// Insert getObject requests into responses map.
|
||||
for (var object in response['result']['objects']) {
|
||||
final requestUri =
|
||||
|
|
Loading…
Reference in a new issue