[vm, isolate] Refactor isolate message snapshotting to centralize construction of the Message.

Remove unused special case in ApiMessageWriter for lists of int.

This is in preparation for ensuring we always free any external data that ends up in an isolate message.

Bug: https://github.com/dart-lang/sdk/issues/31959
Change-Id: I999656fc11d2aee9aebe70852be5bb075f234b4d
Reviewed-on: https://dart-review.googlesource.com/41020
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak
2018-02-14 00:28:01 +00:00
committed by commit-bot@chromium.org
parent 392062c617
commit 3f40488ec4
18 changed files with 486 additions and 676 deletions
+15 -38
View File
@@ -25,17 +25,6 @@
namespace dart {
static uint8_t* malloc_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);
}
static void malloc_deallocator(uint8_t* ptr) {
free(reinterpret_cast<void*>(ptr));
}
DEFINE_NATIVE_ENTRY(CapabilityImpl_factory, 1) {
ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull());
uint64_t id = isolate->random()->NextUInt64();
@@ -106,15 +95,10 @@ DEFINE_NATIVE_ENTRY(SendPortImpl_sendInternal_, 2) {
PortMap::PostMessage(
new Message(destination_port_id, obj.raw(), Message::kNormalPriority));
} else {
uint8_t* data = NULL;
MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator,
can_send_any_object);
writer.WriteMessage(obj);
MessageWriter writer(can_send_any_object);
// TODO(turnidge): Throw an exception when the return value is false?
PortMap::PostMessage(new Message(destination_port_id, data,
writer.BytesWritten(),
Message::kNormalPriority));
PortMap::PostMessage(writer.WriteMessage(obj, destination_port_id,
Message::kNormalPriority));
}
return Object::null();
}
@@ -228,11 +212,9 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 10) {
// serializable this will throw an exception.
SerializedObjectBuffer message_buffer;
{
MessageWriter writer(message_buffer.data_buffer(), &malloc_allocator,
&malloc_deallocator,
/* can_send_any_object = */ true,
message_buffer.data_length());
writer.WriteMessage(message);
MessageWriter writer(/* can_send_any_object = */ true);
message_buffer.set_message(writer.WriteMessage(
message, ILLEGAL_PORT, Message::kNormalPriority));
}
const char* utf8_package_root =
@@ -341,16 +323,14 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) {
SerializedObjectBuffer arguments_buffer;
SerializedObjectBuffer message_buffer;
{
MessageWriter writer(
arguments_buffer.data_buffer(), &malloc_allocator, &malloc_deallocator,
/* can_send_any_object = */ false, arguments_buffer.data_length());
writer.WriteMessage(args);
MessageWriter writer(/* can_send_any_object = */ false);
arguments_buffer.set_message(
writer.WriteMessage(args, ILLEGAL_PORT, Message::kNormalPriority));
}
{
MessageWriter writer(
message_buffer.data_buffer(), &malloc_allocator, &malloc_deallocator,
/* can_send_any_object = */ false, message_buffer.data_length());
writer.WriteMessage(message);
MessageWriter writer(/* can_send_any_object = */ false);
message_buffer.set_message(
writer.WriteMessage(message, ILLEGAL_PORT, Message::kNormalPriority));
}
// Canonicalize the uri with respect to the current isolate.
@@ -420,12 +400,9 @@ DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 2) {
// Make sure to route this request to the isolate library OOB mesage handler.
msg.SetAt(0, Smi::Handle(Smi::New(Message::kIsolateLibOOBMsg)));
uint8_t* data = NULL;
MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false);
writer.WriteMessage(msg);
PortMap::PostMessage(new Message(port.Id(), data, writer.BytesWritten(),
Message::kOOBPriority));
MessageWriter writer(false);
PortMap::PostMessage(
writer.WriteMessage(msg, port.Id(), Message::kOOBPriority));
// Drain interrupts before running so any IMMEDIATE operations on the current
// isolate happen synchronously.
+2 -16
View File
@@ -23,17 +23,6 @@ namespace dart {
DECLARE_FLAG(bool, trace_service);
DECLARE_FLAG(bool, show_kernel_isolate);
static uint8_t* malloc_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);
}
static void malloc_deallocator(uint8_t* ptr) {
free(reinterpret_cast<void*>(ptr));
}
#ifndef PRODUCT
class RegisterRunningIsolatesVisitor : public IsolateVisitor {
public:
@@ -107,13 +96,10 @@ DEFINE_NATIVE_ENTRY(VMService_SendIsolateServiceMessage, 2) {
Smi::Handle(thread->zone(), Smi::New(Message::kServiceOOBMsg)));
// Serialize message.
uint8_t* data = NULL;
MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false);
writer.WriteMessage(message);
MessageWriter writer(false);
// TODO(turnidge): Throw an exception when the return value is false?
bool result = PortMap::PostMessage(
new Message(sp.Id(), data, writer.BytesWritten(), Message::kOOBPriority));
writer.WriteMessage(message, sp.Id(), Message::kOOBPriority));
return Bool::Get(result).raw();
}
+20 -36
View File
@@ -482,10 +482,6 @@ static uint8_t* malloc_allocator(uint8_t* ptr,
return reinterpret_cast<uint8_t*>(realloc(ptr, new_size));
}
static void malloc_deallocator(uint8_t* ptr) {
free(ptr);
}
BENCHMARK_SIZE(CoreSnapshotSize) {
const char* kScriptChars =
"import 'dart:async';\n"
@@ -597,31 +593,22 @@ BENCHMARK(EnterExitIsolate) {
benchmark->set_score(elapsed_time);
}
static uint8_t message_buffer[64];
static uint8_t* message_allocator(uint8_t* ptr,
intptr_t old_size,
intptr_t new_size) {
return message_buffer;
}
static void message_deallocator(uint8_t* ptr) {}
BENCHMARK(SerializeNull) {
TransitionNativeToVM transition(thread);
const Object& null_object = Object::Handle();
const intptr_t kLoopCount = 1000000;
uint8_t* buffer;
Timer timer(true, "Serialize Null");
timer.Start();
for (intptr_t i = 0; i < kLoopCount; i++) {
StackZone zone(thread);
MessageWriter writer(&buffer, &message_allocator, &message_deallocator,
true);
writer.WriteMessage(null_object);
intptr_t buffer_len = writer.BytesWritten();
MessageWriter writer(true);
Message* message = writer.WriteMessage(null_object, ILLEGAL_PORT,
Message::kNormalPriority);
// Read object back from the snapshot.
MessageSnapshotReader reader(buffer, buffer_len, thread);
MessageSnapshotReader reader(message, thread);
reader.ReadObject();
delete message;
}
timer.Stop();
int64_t elapsed_time = timer.TotalElapsedTime();
@@ -632,19 +619,18 @@ BENCHMARK(SerializeSmi) {
TransitionNativeToVM transition(thread);
const Integer& smi_object = Integer::Handle(Smi::New(42));
const intptr_t kLoopCount = 1000000;
uint8_t* buffer;
Timer timer(true, "Serialize Smi");
timer.Start();
for (intptr_t i = 0; i < kLoopCount; i++) {
StackZone zone(thread);
MessageWriter writer(&buffer, &message_allocator, &message_deallocator,
true);
writer.WriteMessage(smi_object);
intptr_t buffer_len = writer.BytesWritten();
MessageWriter writer(true);
Message* message =
writer.WriteMessage(smi_object, ILLEGAL_PORT, Message::kNormalPriority);
// Read object back from the snapshot.
MessageSnapshotReader reader(buffer, buffer_len, thread);
MessageSnapshotReader reader(message, thread);
reader.ReadObject();
delete message;
}
timer.Stop();
int64_t elapsed_time = timer.TotalElapsedTime();
@@ -657,19 +643,18 @@ BENCHMARK(SimpleMessage) {
array_object.SetAt(0, Integer::Handle(Smi::New(42)));
array_object.SetAt(1, Object::Handle());
const intptr_t kLoopCount = 1000000;
uint8_t* buffer;
Timer timer(true, "Simple Message");
timer.Start();
for (intptr_t i = 0; i < kLoopCount; i++) {
StackZone zone(thread);
MessageWriter writer(&buffer, &malloc_allocator, &malloc_deallocator, true);
writer.WriteMessage(array_object);
intptr_t buffer_len = writer.BytesWritten();
MessageWriter writer(true);
Message* message = writer.WriteMessage(array_object, ILLEGAL_PORT,
Message::kNormalPriority);
// Read object back from the snapshot.
MessageSnapshotReader reader(buffer, buffer_len, thread);
MessageSnapshotReader reader(message, thread);
reader.ReadObject();
free(buffer);
delete message;
}
timer.Stop();
int64_t elapsed_time = timer.TotalElapsedTime();
@@ -690,19 +675,18 @@ BENCHMARK(LargeMap) {
Instance& map = Instance::Handle();
map ^= Api::UnwrapHandle(h_result);
const intptr_t kLoopCount = 100;
uint8_t* buffer;
Timer timer(true, "Large Map");
timer.Start();
for (intptr_t i = 0; i < kLoopCount; i++) {
StackZone zone(thread);
MessageWriter writer(&buffer, &malloc_allocator, &malloc_deallocator, true);
writer.WriteMessage(map);
intptr_t buffer_len = writer.BytesWritten();
MessageWriter writer(true);
Message* message =
writer.WriteMessage(map, ILLEGAL_PORT, Message::kNormalPriority);
// Read object back from the snapshot.
MessageSnapshotReader reader(buffer, buffer_len, thread);
MessageSnapshotReader reader(message, thread);
reader.ReadObject();
free(buffer);
delete message;
}
timer.Stop();
int64_t elapsed_time = timer.TotalElapsedTime();
+4 -17
View File
@@ -1544,8 +1544,9 @@ Dart_CreateScriptSnapshot(uint8_t** script_snapshot_buffer,
}
#endif // #if defined(DEBUG)
ScriptSnapshotWriter writer(script_snapshot_buffer, ApiReallocate);
ScriptSnapshotWriter writer(ApiReallocate);
writer.WriteScriptSnapshot(lib);
*script_snapshot_buffer = writer.buffer();
*script_snapshot_size = writer.BytesWritten();
return Api::Success();
}
@@ -1759,17 +1760,6 @@ DART_EXPORT bool Dart_HasLivePorts() {
return isolate->message_handler()->HasLivePorts();
}
static uint8_t* malloc_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);
}
static void malloc_deallocator(uint8_t* ptr) {
free(reinterpret_cast<void*>(ptr));
}
DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) {
DARTSCOPE(Thread::Current());
API_TIMELINE_DURATION;
@@ -1786,12 +1776,9 @@ DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) {
}
const Object& object = Object::Handle(Z, raw_obj);
uint8_t* data = NULL;
MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false);
writer.WriteMessage(object);
intptr_t len = writer.BytesWritten();
MessageWriter writer(false);
return PortMap::PostMessage(
new Message(port_id, data, len, Message::kNormalPriority));
writer.WriteMessage(object, port_id, Message::kNormalPriority));
}
DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) {
+24 -27
View File
@@ -12,13 +12,6 @@ namespace dart {
static const int kNumInitialReferences = 4;
ApiMessageReader::ApiMessageReader(const uint8_t* buffer, intptr_t length)
: BaseReader(buffer, length),
zone_(NULL),
backward_references_(kNumInitialReferences),
vm_isolate_references_(kNumInitialReferences),
vm_symbol_references_(NULL) {}
ApiMessageReader::ApiMessageReader(Message* msg)
: BaseReader(msg->IsRaw() ? reinterpret_cast<uint8_t*>(msg->raw_obj())
: msg->data(),
@@ -857,24 +850,24 @@ Dart_CObject* ApiMessageReader::GetBackRef(intptr_t id) {
return NULL;
}
void ApiMessageWriter::WriteMessage(intptr_t field_count, intptr_t* data) {
// Write out the serialization header value for this object.
WriteInlinedObjectHeader(kMaxPredefinedObjectIds);
static uint8_t* malloc_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);
}
// Write out the class and tags information.
WriteIndexedObject(kArrayCid);
WriteTags(0);
ApiMessageWriter::ApiMessageWriter()
: BaseWriter(malloc_allocator, NULL, kInitialSize),
object_id_(0),
forward_list_(NULL),
forward_list_length_(0),
forward_id_(0) {
ASSERT(kDartCObjectTypeMask >= Dart_CObject_kNumberOfTypes - 1);
}
// Write out the length field.
Write<RawObject*>(Smi::New(field_count));
// Write out the type arguments.
WriteNullObject();
// Write out the individual Smis.
for (int i = 0; i < field_count; i++) {
Write<RawObject*>(Integer::New(data[i]));
}
ApiMessageWriter::~ApiMessageWriter() {
::free(forward_list_);
}
void ApiMessageWriter::MarkCObject(Dart_CObject* object, intptr_t object_id) {
@@ -1253,11 +1246,14 @@ bool ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object,
return true;
}
bool ApiMessageWriter::WriteCMessage(Dart_CObject* object) {
Message* ApiMessageWriter::WriteCMessage(Dart_CObject* object,
Dart_Port dest_port,
Message::Priority priority) {
bool success = WriteCObject(object);
if (!success) {
UnmarkAllCObjects(object);
return false;
free(buffer());
return NULL;
}
// Write out all objects that were added to the forward list and have
// not been serialized yet. These would typically be fields of arrays.
@@ -1266,11 +1262,12 @@ bool ApiMessageWriter::WriteCMessage(Dart_CObject* object) {
success = WriteForwardedCObject(forward_list_[i]);
if (!success) {
UnmarkAllCObjects(object);
return false;
free(buffer());
return NULL;
}
}
UnmarkAllCObjects(object);
return true;
return new Message(dest_port, buffer(), BytesWritten(), priority);
}
} // namespace dart
+5 -14
View File
@@ -47,7 +47,6 @@ class ApiMessageReader : public BaseReader {
// The ApiMessageReader object must be enclosed by an ApiNativeScope.
// Allocation of all C Heap objects is done in the zone associated with
// the enclosing ApiNativeScope.
ApiMessageReader(const uint8_t* buffer, intptr_t length);
explicit ApiMessageReader(Message* message);
~ApiMessageReader() {}
@@ -155,21 +154,13 @@ class ApiMessageReader : public BaseReader {
class ApiMessageWriter : public BaseWriter {
public:
static const intptr_t kInitialSize = 512;
ApiMessageWriter(uint8_t** buffer, ReAlloc alloc)
: BaseWriter(buffer, alloc, NULL, kInitialSize),
object_id_(0),
forward_list_(NULL),
forward_list_length_(0),
forward_id_(0) {
ASSERT(kDartCObjectTypeMask >= Dart_CObject_kNumberOfTypes - 1);
}
~ApiMessageWriter() { ::free(forward_list_); }
// Writes a message of integers.
void WriteMessage(intptr_t field_count, intptr_t* data);
ApiMessageWriter();
~ApiMessageWriter();
// Writes a message with a single object.
bool WriteCMessage(Dart_CObject* object);
Message* WriteCMessage(Dart_CObject* object,
Dart_Port dest_port,
Message::Priority priority);
private:
static const intptr_t kDartCObjectTypeBits = 4;
+21 -58
View File
@@ -117,36 +117,13 @@ class VerifyOriginId : public IsolateVisitor {
};
#endif
static uint8_t* malloc_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);
}
static void malloc_deallocator(uint8_t* ptr) {
free(reinterpret_cast<void*>(ptr));
}
static void SerializeObject(const Instance& obj,
uint8_t** obj_data,
intptr_t* obj_len,
bool allow_any_object) {
MessageWriter writer(obj_data, &malloc_allocator, &malloc_deallocator,
allow_any_object);
writer.WriteMessage(obj);
*obj_len = writer.BytesWritten();
}
// TODO(zra): Allocation of Message objects should be centralized.
static Message* SerializeMessage(Dart_Port dest_port, const Instance& obj) {
if (ApiObjectConverter::CanConvert(obj.raw())) {
return new Message(dest_port, obj.raw(), Message::kNormalPriority);
} else {
uint8_t* obj_data;
intptr_t obj_len;
SerializeObject(obj, &obj_data, &obj_len, false);
return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority);
MessageWriter writer(false);
return writer.WriteMessage(obj, dest_port, Message::kNormalPriority);
}
}
@@ -248,12 +225,9 @@ void Isolate::SendInternalLibMessage(LibMsgId msg_id, uint64_t capability) {
element = Capability::New(capability);
msg.SetAt(2, element);
uint8_t* data = NULL;
MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false);
writer.WriteMessage(msg);
PortMap::PostMessage(new Message(main_port(), data, writer.BytesWritten(),
Message::kOOBPriority));
MessageWriter writer(false);
PortMap::PostMessage(
writer.WriteMessage(msg, main_port(), Message::kOOBPriority));
}
class IsolateMessageHandler : public MessageHandler {
@@ -538,7 +512,7 @@ MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage(
// We should only be sending RawObjects that can be converted to CObjects.
ASSERT(ApiObjectConverter::CanConvert(msg_obj.raw()));
} else {
MessageSnapshotReader reader(message->data(), message->len(), thread);
MessageSnapshotReader reader(message, thread);
msg_obj = reader.ReadObject();
}
if (msg_obj.IsError()) {
@@ -2624,14 +2598,13 @@ void Isolate::KillLocked(LibMsgId msg_id) {
list_values[3] = &imm;
{
uint8_t* buffer = NULL;
ApiMessageWriter writer(&buffer, &malloc_allocator);
bool success = writer.WriteCMessage(&kill_msg);
ASSERT(success);
ApiMessageWriter writer;
Message* message =
writer.WriteCMessage(&kill_msg, main_port(), Message::kOOBPriority);
ASSERT(message != NULL);
// Post the message at the given port.
success = PortMap::PostMessage(new Message(
main_port(), buffer, writer.BytesWritten(), Message::kOOBPriority));
bool success = PortMap::PostMessage(message);
ASSERT(success);
}
}
@@ -2798,13 +2771,11 @@ void Isolate::UnscheduleThread(Thread* thread,
thread_registry()->ReturnThreadLocked(is_mutator, thread);
}
static RawInstance* DeserializeObject(Thread* thread,
uint8_t* obj_data,
intptr_t obj_len) {
if (obj_data == NULL) {
static RawInstance* DeserializeObject(Thread* thread, Message* message) {
if (message == NULL) {
return Instance::null();
}
MessageSnapshotReader reader(obj_data, obj_len, thread);
MessageSnapshotReader reader(message, thread);
Zone* zone = thread->zone();
const Object& obj = Object::Handle(zone, reader.ReadObject());
ASSERT(!obj.IsError());
@@ -2847,9 +2818,7 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
class_name_(NULL),
function_name_(NULL),
serialized_args_(NULL),
serialized_args_len_(0),
serialized_message_(NULL),
serialized_message_len_(0),
serialized_message_(message_buffer->StealMessage()),
spawn_count_monitor_(spawn_count_monitor),
spawn_count_(spawn_count),
paused_(paused),
@@ -2867,7 +2836,6 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
const String& class_name = String::Handle(cls.Name());
class_name_ = NewConstChar(class_name.ToCString());
}
message_buffer->StealBuffer(&serialized_message_, &serialized_message_len_);
// Inherit flags from spawning isolate.
Isolate::Current()->FlagsCopyTo(isolate_flags());
@@ -2898,18 +2866,14 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
library_url_(NULL),
class_name_(NULL),
function_name_(NULL),
serialized_args_(NULL),
serialized_args_len_(0),
serialized_message_(NULL),
serialized_message_len_(0),
serialized_args_(args_buffer->StealMessage()),
serialized_message_(message_buffer->StealMessage()),
spawn_count_monitor_(spawn_count_monitor),
spawn_count_(spawn_count),
isolate_flags_(),
paused_(paused),
errors_are_fatal_(errors_are_fatal) {
function_name_ = NewConstChar("main");
args_buffer->StealBuffer(&serialized_args_, &serialized_args_len_);
message_buffer->StealBuffer(&serialized_message_, &serialized_message_len_);
// By default inherit flags from spawning isolate. These can be overridden
// from the calling code.
@@ -2923,8 +2887,8 @@ IsolateSpawnState::~IsolateSpawnState() {
delete[] library_url_;
delete[] class_name_;
delete[] function_name_;
free(serialized_args_);
free(serialized_message_);
delete serialized_args_;
delete serialized_message_;
}
RawObject* IsolateSpawnState::ResolveFunction() {
@@ -3005,12 +2969,11 @@ RawObject* IsolateSpawnState::ResolveFunction() {
}
RawInstance* IsolateSpawnState::BuildArgs(Thread* thread) {
return DeserializeObject(thread, serialized_args_, serialized_args_len_);
return DeserializeObject(thread, serialized_args_);
}
RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) {
return DeserializeObject(thread, serialized_message_,
serialized_message_len_);
return DeserializeObject(thread, serialized_message_);
}
void IsolateSpawnState::DecrementSpawnCount() {
+3 -4
View File
@@ -42,6 +42,7 @@ class IsolateProfilerData;
class IsolateReloadContext;
class IsolateSpawnState;
class Log;
class Message;
class MessageHandler;
class Mutex;
class Object;
@@ -1125,10 +1126,8 @@ class IsolateSpawnState {
const char* library_url_;
const char* class_name_;
const char* function_name_;
uint8_t* serialized_args_;
intptr_t serialized_args_len_;
uint8_t* serialized_message_;
intptr_t serialized_message_len_;
Message* serialized_args_;
Message* serialized_message_;
// This counter tracks the number of outstanding calls to spawn by the parent
// isolate.
+37
View File
@@ -11,6 +11,43 @@
namespace dart {
Message::Message(Dart_Port dest_port,
uint8_t* data,
intptr_t len,
Priority priority,
Dart_Port delivery_failure_port)
: next_(NULL),
dest_port_(dest_port),
delivery_failure_port_(delivery_failure_port),
data_(data),
len_(len),
priority_(priority) {
ASSERT((priority == kNormalPriority) ||
(delivery_failure_port == kIllegalPort));
}
Message::Message(Dart_Port dest_port,
RawObject* raw_obj,
Priority priority,
Dart_Port delivery_failure_port)
: next_(NULL),
dest_port_(dest_port),
delivery_failure_port_(delivery_failure_port),
data_(reinterpret_cast<uint8_t*>(raw_obj)),
len_(0),
priority_(priority) {
ASSERT(!raw_obj->IsHeapObject() || raw_obj->IsVMHeapObject());
ASSERT((priority == kNormalPriority) ||
(delivery_failure_port == kIllegalPort));
}
Message::~Message() {
ASSERT(delivery_failure_port_ == kIllegalPort);
if (len_ > 0) {
free(data_);
}
}
bool Message::RedirectToDeliveryFailurePort() {
if (delivery_failure_port_ == kIllegalPort) {
return false;
+4 -28
View File
@@ -8,7 +8,6 @@
#include "platform/assert.h"
#include "vm/allocation.h"
#include "vm/globals.h"
#include "vm/raw_object.h"
// Duplicated from dart_api.h to avoid including the whole header.
typedef int64_t Dart_Port;
@@ -16,6 +15,7 @@ typedef int64_t Dart_Port;
namespace dart {
class JSONStream;
class RawObject;
class Message {
public:
@@ -48,39 +48,15 @@ class Message {
uint8_t* data,
intptr_t len,
Priority priority,
Dart_Port delivery_failure_port = kIllegalPort)
: next_(NULL),
dest_port_(dest_port),
delivery_failure_port_(delivery_failure_port),
data_(data),
len_(len),
priority_(priority) {
ASSERT((priority == kNormalPriority) ||
(delivery_failure_port == kIllegalPort));
}
Dart_Port delivery_failure_port = kIllegalPort);
// Message objects can also carry RawObject pointers for Smis and objects in
// the VM heap. This is indicated by setting the len_ field to 0.
Message(Dart_Port dest_port,
RawObject* raw_obj,
Priority priority,
Dart_Port delivery_failure_port = kIllegalPort)
: next_(NULL),
dest_port_(dest_port),
delivery_failure_port_(delivery_failure_port),
data_(reinterpret_cast<uint8_t*>(raw_obj)),
len_(0),
priority_(priority) {
ASSERT(!raw_obj->IsHeapObject() || raw_obj->IsVMHeapObject());
ASSERT((priority == kNormalPriority) ||
(delivery_failure_port == kIllegalPort));
}
~Message() {
ASSERT(delivery_failure_port_ == kIllegalPort);
if (len_ > 0) {
free(data_);
}
}
Dart_Port delivery_failure_port = kIllegalPort);
~Message();
Dart_Port dest_port() const { return dest_port_; }
uint8_t* data() const {
+6 -15
View File
@@ -16,13 +16,6 @@ namespace dart {
// --- Message sending/receiving from native code ---
static uint8_t* malloc_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);
}
class IsolateSaver {
public:
explicit IsolateSaver(Isolate* current_isolate)
@@ -46,18 +39,16 @@ class IsolateSaver {
};
static bool PostCObjectHelper(Dart_Port port_id, Dart_CObject* message) {
uint8_t* buffer = NULL;
ApiMessageWriter writer(&buffer, malloc_allocator);
bool success = writer.WriteCMessage(message);
ApiMessageWriter writer;
Message* msg =
writer.WriteCMessage(message, port_id, Message::kNormalPriority);
if (!success) {
free(buffer);
return success;
if (msg == NULL) {
return false;
}
// Post the message at the given port.
return PortMap::PostMessage(new Message(
port_id, buffer, writer.BytesWritten(), Message::kNormalPriority));
return PortMap::PostMessage(msg);
}
DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) {
+1 -1
View File
@@ -1830,7 +1830,7 @@ static RawObject* LookupHeapObjectMessage(Thread* thread,
return Object::sentinel().raw();
}
if (message->len() > 0) {
MessageSnapshotReader reader(message->data(), message->len(), thread);
MessageSnapshotReader reader(message, thread);
return reader.ReadObject();
} else {
return message->raw_obj();
+25 -68
View File
@@ -6,6 +6,7 @@
#include "vm/compiler/jit/compiler.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_api_message.h"
#include "vm/dart_entry.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
@@ -35,17 +36,6 @@ DEFINE_FLAG(bool,
false,
"Provide extra service tracing information.");
static uint8_t* malloc_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);
}
static void malloc_deallocator(uint8_t* ptr) {
free(reinterpret_cast<void*>(ptr));
}
// These must be kept in sync with service/constants.dart
#define VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID 0
#define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
@@ -80,23 +70,12 @@ static RawArray* MakeServerControlMessage(const SendPort& sp,
return list.raw();
}
static RawArray* MakeServiceExitMessage() {
const Array& list = Array::Handle(Array::New(1));
ASSERT(!list.IsNull());
const intptr_t code = VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID;
const Integer& code_int = Integer::Handle(Integer::New(code));
list.SetAt(0, code_int);
return list.raw();
}
const char* ServiceIsolate::kName = "vm-service";
Isolate* ServiceIsolate::isolate_ = NULL;
Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT;
Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT;
Dart_Port ServiceIsolate::origin_ = ILLEGAL_PORT;
Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL;
uint8_t* ServiceIsolate::exit_message_ = NULL;
intptr_t ServiceIsolate::exit_message_length_ = 0;
Monitor* ServiceIsolate::monitor_ = new Monitor();
bool ServiceIsolate::initializing_ = true;
bool ServiceIsolate::shutting_down_ = false;
@@ -106,22 +85,18 @@ void ServiceIsolate::RequestServerInfo(const SendPort& sp) {
const Array& message = Array::Handle(MakeServerControlMessage(
sp, VM_SERVICE_SERVER_INFO_MESSAGE_ID, false /* ignored */));
ASSERT(!message.IsNull());
uint8_t* data = NULL;
MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false);
writer.WriteMessage(message);
intptr_t len = writer.BytesWritten();
PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority));
MessageWriter writer(false);
PortMap::PostMessage(
writer.WriteMessage(message, port_, Message::kNormalPriority));
}
void ServiceIsolate::ControlWebServer(const SendPort& sp, bool enable) {
const Array& message = Array::Handle(MakeServerControlMessage(
sp, VM_SERVICE_WEB_SERVER_CONTROL_MESSAGE_ID, enable));
ASSERT(!message.IsNull());
uint8_t* data = NULL;
MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false);
writer.WriteMessage(message);
intptr_t len = writer.BytesWritten();
PortMap::PostMessage(new Message(port_, data, len, Message::kNormalPriority));
MessageWriter writer(false);
PortMap::PostMessage(
writer.WriteMessage(message, port_, Message::kNormalPriority));
}
void ServiceIsolate::SetServerAddress(const char* address) {
@@ -194,16 +169,13 @@ bool ServiceIsolate::SendIsolateStartupMessage() {
const Array& list = Array::Handle(MakeServiceControlMessage(
Dart_GetMainPortId(), VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, name));
ASSERT(!list.IsNull());
uint8_t* data = NULL;
MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false);
writer.WriteMessage(list);
intptr_t len = writer.BytesWritten();
MessageWriter writer(false);
if (FLAG_trace_service) {
OS::PrintErr("vm-service: Isolate %s %" Pd64 " registered.\n",
name.ToCString(), Dart_GetMainPortId());
}
return PortMap::PostMessage(
new Message(port_, data, len, Message::kNormalPriority));
writer.WriteMessage(list, port_, Message::kNormalPriority));
}
bool ServiceIsolate::SendIsolateShutdownMessage() {
@@ -222,30 +194,36 @@ bool ServiceIsolate::SendIsolateShutdownMessage() {
const Array& list = Array::Handle(MakeServiceControlMessage(
Dart_GetMainPortId(), VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, name));
ASSERT(!list.IsNull());
uint8_t* data = NULL;
MessageWriter writer(&data, &malloc_allocator, &malloc_deallocator, false);
writer.WriteMessage(list);
intptr_t len = writer.BytesWritten();
MessageWriter writer(false);
if (FLAG_trace_service) {
OS::PrintErr("vm-service: Isolate %s %" Pd64 " deregistered.\n",
name.ToCString(), Dart_GetMainPortId());
}
return PortMap::PostMessage(
new Message(port_, data, len, Message::kNormalPriority));
writer.WriteMessage(list, port_, Message::kNormalPriority));
}
void ServiceIsolate::SendServiceExitMessage() {
if (!IsRunning()) {
return;
}
if ((exit_message_ == NULL) || (exit_message_length_ == 0)) {
return;
}
if (FLAG_trace_service) {
OS::PrintErr("vm-service: sending service exit message.\n");
}
PortMap::PostMessage(new Message(port_, exit_message_, exit_message_length_,
Message::kNormalPriority));
Dart_CObject code;
code.type = Dart_CObject_kInt32;
code.value.as_int32 = VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID;
Dart_CObject* values[1] = {&code};
Dart_CObject message;
message.type = Dart_CObject_kArray;
message.value.as_array.length = 1;
message.value.as_array.values = values;
ApiMessageWriter writer;
PortMap::PostMessage(
writer.WriteCMessage(&message, port_, Message::kNormalPriority));
}
void ServiceIsolate::SetServicePort(Dart_Port port) {
@@ -283,26 +261,6 @@ void ServiceIsolate::MaybeMakeServiceIsolate(Isolate* I) {
SetServiceIsolate(I);
}
void ServiceIsolate::ConstructExitMessageAndCache(Isolate* I) {
// Construct and cache exit message here so we can send it without needing an
// isolate.
Thread* T = Thread::Current();
ASSERT(I == T->isolate());
ASSERT(I != NULL);
StackZone zone(T);
HANDLESCOPE(T);
ASSERT(exit_message_ == NULL);
ASSERT(exit_message_length_ == 0);
const Array& list = Array::Handle(Z, MakeServiceExitMessage());
ASSERT(!list.IsNull());
MessageWriter writer(&exit_message_, &malloc_allocator, &malloc_deallocator,
false);
writer.WriteMessage(list);
exit_message_length_ = writer.BytesWritten();
ASSERT(exit_message_ != NULL);
ASSERT(exit_message_length_ != 0);
}
void ServiceIsolate::FinishedExiting() {
MonitorLocker ml(monitor_);
shutting_down_ = false;
@@ -348,7 +306,6 @@ class RunServiceTask : public ThreadPool::Task {
{
ASSERT(Isolate::Current() == NULL);
StartIsolateScope start_scope(isolate);
ServiceIsolate::ConstructExitMessageAndCache(isolate);
got_unwind = RunMain(isolate);
}
-3
View File
@@ -54,7 +54,6 @@ class ServiceIsolate : public AllStatic {
static void SetServicePort(Dart_Port port);
static void SetServiceIsolate(Isolate* isolate);
static void SetLoadPort(Dart_Port port);
static void ConstructExitMessageAndCache(Isolate* isolate);
static void FinishedExiting();
static void FinishedInitializing();
static void MaybeMakeServiceIsolate(Isolate* isolate);
@@ -63,8 +62,6 @@ class ServiceIsolate : public AllStatic {
}
static Dart_IsolateCreateCallback create_callback_;
static uint8_t* exit_message_;
static intptr_t exit_message_length_;
static Monitor* monitor_;
static bool initializing_;
static bool shutting_down_;
+1 -1
View File
@@ -44,7 +44,7 @@ class ServiceTestMessageHandler : public MessageHandler {
response_obj = message->raw_obj();
} else {
Thread* thread = Thread::Current();
MessageSnapshotReader reader(message->data(), message->len(), thread);
MessageSnapshotReader reader(message, thread);
response_obj = reader.ReadObject();
}
if (response_obj.IsString()) {
+25 -27
View File
@@ -918,11 +918,9 @@ ScriptSnapshotReader::~ScriptSnapshotReader() {
ResetBackwardReferenceTable();
}
MessageSnapshotReader::MessageSnapshotReader(const uint8_t* buffer,
intptr_t size,
Thread* thread)
: SnapshotReader(buffer,
size,
MessageSnapshotReader::MessageSnapshotReader(Message* message, Thread* thread)
: SnapshotReader(message->data(),
message->len(),
Snapshot::kMessage,
new ZoneGrowableArray<BackRefNode>(kNumInitialReferences),
thread) {}
@@ -933,13 +931,12 @@ MessageSnapshotReader::~MessageSnapshotReader() {
SnapshotWriter::SnapshotWriter(Thread* thread,
Snapshot::Kind kind,
uint8_t** buffer,
ReAlloc alloc,
DeAlloc dealloc,
intptr_t initial_size,
ForwardList* forward_list,
bool can_send_any_object)
: BaseWriter(buffer, alloc, dealloc, initial_size),
: BaseWriter(alloc, dealloc, initial_size),
thread_(thread),
kind_(kind),
object_store_(isolate()->object_store()),
@@ -1546,17 +1543,15 @@ void SnapshotWriter::WriteVersionAndFeatures() {
free(const_cast<char*>(expected_features));
}
ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, ReAlloc alloc)
ScriptSnapshotWriter::ScriptSnapshotWriter(ReAlloc alloc)
: SnapshotWriter(Thread::Current(),
Snapshot::kScript,
buffer,
alloc,
NULL,
kInitialSize,
&forward_list_,
true /* can_send_any_object */),
forward_list_(thread(), kMaxPredefinedObjectIds) {
ASSERT(buffer != NULL);
ASSERT(alloc != NULL);
}
@@ -1598,26 +1593,30 @@ void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) {
}
}
MessageWriter::MessageWriter(uint8_t** buffer,
ReAlloc alloc,
DeAlloc dealloc,
bool can_send_any_object,
intptr_t* buffer_len)
static uint8_t* malloc_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);
}
static void malloc_deallocator(uint8_t* ptr) {
free(reinterpret_cast<void*>(ptr));
}
MessageWriter::MessageWriter(bool can_send_any_object)
: SnapshotWriter(Thread::Current(),
Snapshot::kMessage,
buffer,
alloc,
dealloc,
malloc_allocator,
malloc_deallocator,
kInitialSize,
&forward_list_,
can_send_any_object),
forward_list_(thread(), kMaxPredefinedObjectIds),
buffer_len_(buffer_len) {
ASSERT(buffer != NULL);
ASSERT(alloc != NULL);
}
forward_list_(thread(), kMaxPredefinedObjectIds) {}
void MessageWriter::WriteMessage(const Object& obj) {
Message* MessageWriter::WriteMessage(const Object& obj,
Dart_Port dest_port,
Message::Priority priority) {
ASSERT(kind() == Snapshot::kMessage);
ASSERT(isolate() != NULL);
@@ -1627,13 +1626,12 @@ void MessageWriter::WriteMessage(const Object& obj) {
if (setjmp(*jump.Set()) == 0) {
NoSafepointScope no_safepoint;
WriteObject(obj.raw());
if (buffer_len_ != NULL) {
*buffer_len_ = BytesWritten();
}
} else {
FreeBuffer();
ThrowException(exception_type(), exception_msg());
}
return new Message(dest_port, buffer(), BytesWritten(), priority);
}
} // namespace dart
+23 -33
View File
@@ -12,6 +12,7 @@
#include "vm/globals.h"
#include "vm/growable_array.h"
#include "vm/isolate.h"
#include "vm/message.h"
#include "vm/visitor.h"
namespace dart {
@@ -489,7 +490,7 @@ class ScriptSnapshotReader : public SnapshotReader {
class MessageSnapshotReader : public SnapshotReader {
public:
MessageSnapshotReader(const uint8_t* buffer, intptr_t size, Thread* thread);
MessageSnapshotReader(Message* message, Thread* thread);
~MessageSnapshotReader();
private:
@@ -498,7 +499,7 @@ class MessageSnapshotReader : public SnapshotReader {
class BaseWriter : public StackResource {
public:
// Size of the snapshot.
uint8_t* buffer() { return stream_.buffer(); }
intptr_t BytesWritten() const { return stream_.bytes_written(); }
// Writes raw data to the stream (basic type).
@@ -556,14 +557,11 @@ class BaseWriter : public StackResource {
}
protected:
BaseWriter(uint8_t** buffer,
ReAlloc alloc,
DeAlloc dealloc,
intptr_t initial_size)
BaseWriter(ReAlloc alloc, DeAlloc dealloc, intptr_t initial_size)
: StackResource(Thread::Current()),
stream_(buffer, alloc, initial_size),
buffer_(NULL),
stream_(&buffer_, alloc, initial_size),
dealloc_(dealloc) {
ASSERT(buffer != NULL);
ASSERT(alloc != NULL);
}
~BaseWriter() {}
@@ -585,6 +583,7 @@ class BaseWriter : public StackResource {
}
private:
uint8_t* buffer_;
WriteStream stream_;
DeAlloc dealloc_;
@@ -649,7 +648,6 @@ class SnapshotWriter : public BaseWriter {
protected:
SnapshotWriter(Thread* thread,
Snapshot::Kind kind,
uint8_t** buffer,
ReAlloc alloc,
DeAlloc dealloc,
intptr_t initial_size,
@@ -766,7 +764,7 @@ class SnapshotWriter : public BaseWriter {
class ScriptSnapshotWriter : public SnapshotWriter {
public:
static const intptr_t kInitialSize = 64 * KB;
ScriptSnapshotWriter(uint8_t** buffer, ReAlloc alloc);
explicit ScriptSnapshotWriter(ReAlloc alloc);
~ScriptSnapshotWriter() {}
// Writes a partial snapshot of the script.
@@ -780,44 +778,36 @@ class ScriptSnapshotWriter : public SnapshotWriter {
class SerializedObjectBuffer : public StackResource {
public:
SerializedObjectBuffer()
: StackResource(Thread::Current()),
object_data_(NULL),
object_length_(0) {}
SerializedObjectBuffer() : StackResource(Thread::Current()), message_(NULL) {}
virtual ~SerializedObjectBuffer() { free(object_data_); }
virtual ~SerializedObjectBuffer() { delete message_; }
void StealBuffer(uint8_t** out_data, intptr_t* out_length) {
*out_data = object_data_;
*out_length = object_length_;
object_data_ = NULL;
object_length_ = 0;
void set_message(Message* message) {
ASSERT(message_ == NULL);
message_ = message;
}
Message* StealMessage() {
Message* result = message_;
message_ = NULL;
return result;
}
uint8_t** data_buffer() { return &object_data_; }
intptr_t* data_length() { return &object_length_; }
private:
uint8_t* object_data_;
intptr_t object_length_;
Message* message_;
};
class MessageWriter : public SnapshotWriter {
public:
static const intptr_t kInitialSize = 512;
MessageWriter(uint8_t** buffer,
ReAlloc alloc,
DeAlloc dealloc,
bool can_send_any_object,
intptr_t* buffer_len = NULL);
explicit MessageWriter(bool can_send_any_object);
~MessageWriter() {}
void WriteMessage(const Object& obj);
Message* WriteMessage(const Object& obj,
Dart_Port dest_port,
Message::Priority priority);
private:
ForwardList forward_list_;
intptr_t* buffer_len_;
DISALLOW_COPY_AND_ASSIGN(MessageWriter);
};
File diff suppressed because it is too large Load Diff