From 3f40488ec42175b4e9574eddd3e2fd117b9e258b Mon Sep 17 00:00:00 2001 From: Ryan Macnak Date: Wed, 14 Feb 2018 00:28:01 +0000 Subject: [PATCH] [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 Commit-Queue: Ryan Macnak --- runtime/lib/isolate.cc | 53 +--- runtime/lib/vmservice.cc | 18 +- runtime/vm/benchmark_test.cc | 56 ++-- runtime/vm/dart_api_impl.cc | 21 +- runtime/vm/dart_api_message.cc | 51 ++- runtime/vm/dart_api_message.h | 19 +- runtime/vm/isolate.cc | 79 ++--- runtime/vm/isolate.h | 7 +- runtime/vm/message.cc | 37 +++ runtime/vm/message.h | 32 +- runtime/vm/native_api_impl.cc | 21 +- runtime/vm/service.cc | 2 +- runtime/vm/service_isolate.cc | 93 ++---- runtime/vm/service_isolate.h | 3 - runtime/vm/service_test.cc | 2 +- runtime/vm/snapshot.cc | 52 ++- runtime/vm/snapshot.h | 56 ++-- runtime/vm/snapshot_test.cc | 560 ++++++++++++++++----------------- 18 files changed, 486 insertions(+), 676 deletions(-) diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc index 89084985304..43ff9094f4d 100644 --- a/runtime/lib/isolate.cc +++ b/runtime/lib/isolate.cc @@ -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(ptr), new_size); - return reinterpret_cast(new_ptr); -} - -static void malloc_deallocator(uint8_t* ptr) { - free(reinterpret_cast(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. diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc index df4486274c6..eeeeb506d72 100644 --- a/runtime/lib/vmservice.cc +++ b/runtime/lib/vmservice.cc @@ -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(ptr), new_size); - return reinterpret_cast(new_ptr); -} - -static void malloc_deallocator(uint8_t* ptr) { - free(reinterpret_cast(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(); } diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc index e0764a21758..c29a1446241 100644 --- a/runtime/vm/benchmark_test.cc +++ b/runtime/vm/benchmark_test.cc @@ -482,10 +482,6 @@ static uint8_t* malloc_allocator(uint8_t* ptr, return reinterpret_cast(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(); diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index 6ee6b795635..60a537c6f60 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc @@ -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(ptr), new_size); - return reinterpret_cast(new_ptr); -} - -static void malloc_deallocator(uint8_t* ptr) { - free(reinterpret_cast(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) { diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc index a8ba9dc3e56..09516595bc7 100644 --- a/runtime/vm/dart_api_message.cc +++ b/runtime/vm/dart_api_message.cc @@ -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(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(ptr), new_size); + return reinterpret_cast(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(Smi::New(field_count)); - - // Write out the type arguments. - WriteNullObject(); - - // Write out the individual Smis. - for (int i = 0; i < field_count; i++) { - Write(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 diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h index d2a84e2dd34..349ab5ff277 100644 --- a/runtime/vm/dart_api_message.h +++ b/runtime/vm/dart_api_message.h @@ -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; diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc index e67f6e10e5c..0e1f65a25f6 100644 --- a/runtime/vm/isolate.cc +++ b/runtime/vm/isolate.cc @@ -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(ptr), new_size); - return reinterpret_cast(new_ptr); -} - -static void malloc_deallocator(uint8_t* ptr) { - free(reinterpret_cast(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() { diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h index aef8f401371..2794d137fb1 100644 --- a/runtime/vm/isolate.h +++ b/runtime/vm/isolate.h @@ -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. diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc index 305b4ebac5e..6fa77d8061c 100644 --- a/runtime/vm/message.cc +++ b/runtime/vm/message.cc @@ -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(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; diff --git a/runtime/vm/message.h b/runtime/vm/message.h index 4765ef24195..db4695507d5 100644 --- a/runtime/vm/message.h +++ b/runtime/vm/message.h @@ -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(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 { diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc index 49db21ad921..2f52f304c1c 100644 --- a/runtime/vm/native_api_impl.cc +++ b/runtime/vm/native_api_impl.cc @@ -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(ptr), new_size); - return reinterpret_cast(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) { diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc index f5dd5b82450..82fef8b3ecf 100644 --- a/runtime/vm/service.cc +++ b/runtime/vm/service.cc @@ -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(); diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc index 2c42ec536f7..96acbe548fa 100644 --- a/runtime/vm/service_isolate.cc +++ b/runtime/vm/service_isolate.cc @@ -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(ptr), new_size); - return reinterpret_cast(new_ptr); -} - -static void malloc_deallocator(uint8_t* ptr) { - free(reinterpret_cast(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); } diff --git a/runtime/vm/service_isolate.h b/runtime/vm/service_isolate.h index 90603017b3a..d371e8ed623 100644 --- a/runtime/vm/service_isolate.h +++ b/runtime/vm/service_isolate.h @@ -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_; diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc index 78f6a0cf6d4..c0aec6d8924 100644 --- a/runtime/vm/service_test.cc +++ b/runtime/vm/service_test.cc @@ -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()) { diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc index d801e19fda4..b774bb24329 100644 --- a/runtime/vm/snapshot.cc +++ b/runtime/vm/snapshot.cc @@ -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(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(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(ptr), new_size); + return reinterpret_cast(new_ptr); +} + +static void malloc_deallocator(uint8_t* ptr) { + free(reinterpret_cast(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 diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h index dd7551d3d99..576b501ae95 100644 --- a/runtime/vm/snapshot.h +++ b/runtime/vm/snapshot.h @@ -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); }; diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc index 6e51b3895ec..b2af1a9cd9f 100644 --- a/runtime/vm/snapshot_test.cc +++ b/runtime/vm/snapshot_test.cc @@ -57,19 +57,6 @@ static uint8_t* malloc_allocator(uint8_t* ptr, return reinterpret_cast(realloc(ptr, new_size)); } -static void malloc_deallocator(uint8_t* ptr) { - free(ptr); -} - -static uint8_t* zone_allocator(uint8_t* ptr, - intptr_t old_size, - intptr_t new_size) { - Zone* zone = Thread::Current()->zone(); - return zone->Realloc(ptr, old_size, new_size); -} - -static void zone_deallocator(uint8_t* ptr) {} - // Compare two Dart_CObject object graphs rooted in first and // second. The second graph will be destroyed by this operation no matter // whether the graphs are equal or not. @@ -134,25 +121,23 @@ static void CompareDartCObjects(Dart_CObject* first, Dart_CObject* second) { static void CheckEncodeDecodeMessage(Dart_CObject* root) { // Encode and decode the message. - uint8_t* buffer = NULL; - ApiMessageWriter writer(&buffer, &malloc_allocator); - writer.WriteCMessage(root); + ApiMessageWriter writer; + Message* message = + writer.WriteCMessage(root, ILLEGAL_PORT, Message::kNormalPriority); - ApiMessageReader api_reader(buffer, writer.BytesWritten()); + ApiMessageReader api_reader(message); Dart_CObject* new_root = api_reader.ReadMessage(); + delete message; // Check that the two messages are the same. CompareDartCObjects(root, new_root); - - free(buffer); } static void ExpectEncodeFail(Dart_CObject* root) { - uint8_t* buffer = NULL; - ApiMessageWriter writer(&buffer, &malloc_allocator); - const bool result = writer.WriteCMessage(root); - EXPECT_EQ(false, result); - free(buffer); + ApiMessageWriter writer; + Message* message = + writer.WriteCMessage(root, ILLEGAL_PORT, Message::kNormalPriority); + EXPECT(message == NULL); } TEST_CASE(SerializeNull) { @@ -160,23 +145,24 @@ TEST_CASE(SerializeNull) { // Write snapshot with object content. const Object& null_object = Object::Handle(); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_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); const Object& serialized_object = Object::Handle(reader.ReadObject()); EXPECT(Equals(null_object, serialized_object)); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kNull, root->type); CheckEncodeDecodeMessage(root); + + delete message; } TEST_CASE(SerializeSmi1) { @@ -184,24 +170,25 @@ TEST_CASE(SerializeSmi1) { // Write snapshot with object content. const Smi& smi = Smi::Handle(Smi::New(124)); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(smi); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(smi, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); const Object& serialized_object = Object::Handle(reader.ReadObject()); EXPECT(Equals(smi, serialized_object)); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kInt32, root->type); EXPECT_EQ(smi.Value(), root->value.as_int32); CheckEncodeDecodeMessage(root); + + delete message; } TEST_CASE(SerializeSmi2) { @@ -209,48 +196,49 @@ TEST_CASE(SerializeSmi2) { // Write snapshot with object content. const Smi& smi = Smi::Handle(Smi::New(-1)); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(smi); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(smi, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); const Object& serialized_object = Object::Handle(reader.ReadObject()); EXPECT(Equals(smi, serialized_object)); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kInt32, root->type); EXPECT_EQ(smi.Value(), root->value.as_int32); CheckEncodeDecodeMessage(root); + + delete message; } Dart_CObject* SerializeAndDeserializeMint(const Mint& mint) { // Write snapshot with object content. - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(mint); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(mint, ILLEGAL_PORT, Message::kNormalPriority); { // Switch to a regular zone, where VM handle allocation is allowed. Thread* thread = Thread::Current(); StackZone zone(thread); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); const Object& serialized_object = Object::Handle(reader.ReadObject()); EXPECT(serialized_object.IsMint()); } // Read object back from the snapshot into a C structure. - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); CheckEncodeDecodeMessage(root); + delete message; return root; } @@ -303,24 +291,25 @@ TEST_CASE(SerializeDouble) { // Write snapshot with object content. const Double& dbl = Double::Handle(Double::New(101.29)); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(dbl); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(dbl, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); const Object& serialized_object = Object::Handle(reader.ReadObject()); EXPECT(Equals(dbl, serialized_object)); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kDouble, root->type); EXPECT_EQ(dbl.value(), root->value.as_double); CheckEncodeDecodeMessage(root); + + delete message; } TEST_CASE(SerializeTrue) { @@ -328,13 +317,12 @@ TEST_CASE(SerializeTrue) { // Write snapshot with true object. const Bool& bl = Bool::True(); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(bl); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(bl, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); const Object& serialized_object = Object::Handle(reader.ReadObject()); fprintf(stderr, "%s / %s\n", bl.ToCString(), serialized_object.ToCString()); @@ -342,12 +330,14 @@ TEST_CASE(SerializeTrue) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kBool, root->type); EXPECT_EQ(true, root->value.as_bool); CheckEncodeDecodeMessage(root); + + delete message; } TEST_CASE(SerializeFalse) { @@ -355,36 +345,36 @@ TEST_CASE(SerializeFalse) { // Write snapshot with false object. const Bool& bl = Bool::False(); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(bl); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(bl, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); const Object& serialized_object = Object::Handle(reader.ReadObject()); EXPECT(Equals(bl, serialized_object)); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kBool, root->type); EXPECT_EQ(false, root->value.as_bool); CheckEncodeDecodeMessage(root); + + delete message; } TEST_CASE(SerializeCapability) { // Write snapshot with object content. const Capability& capability = Capability::Handle(Capability::New(12345)); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(capability); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(capability, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); Capability& obj = Capability::Handle(); obj ^= reader.ReadObject(); @@ -392,13 +382,14 @@ TEST_CASE(SerializeCapability) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kCapability, root->type); int64_t id = root->value.as_capability.id; EXPECT_EQ(12345, id); CheckEncodeDecodeMessage(root); + delete message; } TEST_CASE(SerializeBigint) { @@ -410,13 +401,12 @@ TEST_CASE(SerializeBigint) { const String& str = String::Handle(String::New(cstr)); Bigint& bigint = Bigint::Handle(); bigint ^= Integer::NewCanonical(str); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(bigint); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(bigint, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); Bigint& obj = Bigint::Handle(); obj ^= reader.ReadObject(); @@ -425,7 +415,7 @@ TEST_CASE(SerializeBigint) { // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kBigint, root->type); @@ -433,21 +423,22 @@ TEST_CASE(SerializeBigint) { EXPECT_STREQ(cstr, hex_value); free(hex_value); CheckEncodeDecodeMessage(root); + + delete message; } Dart_CObject* SerializeAndDeserializeBigint(const Bigint& bigint) { // Write snapshot with object content. - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(bigint); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(bigint, ILLEGAL_PORT, Message::kNormalPriority); { // Switch to a regular zone, where VM handle allocation is allowed. Thread* thread = Thread::Current(); StackZone zone(thread); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); Bigint& serialized_bigint = Bigint::Handle(); serialized_bigint ^= reader.ReadObject(); const char* str1 = bigint.ToHexCString(thread->zone()); @@ -456,11 +447,14 @@ Dart_CObject* SerializeAndDeserializeBigint(const Bigint& bigint) { } // Read object back from the snapshot into a C structure. - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); // Bigint not supported. EXPECT_NOTNULL(root); CheckEncodeDecodeMessage(root); + + delete message; + return root; } @@ -489,42 +483,30 @@ TEST_CASE(SerializeBigint2) { CheckBigint("-0x9876543210987654321098765432109876543210"); } +#define TEST_ROUND_TRIP_IDENTICAL(object) \ + { \ + MessageWriter writer(true); \ + Message* message = writer.WriteMessage( \ + Object::Handle(object), ILLEGAL_PORT, Message::kNormalPriority); \ + MessageSnapshotReader reader(message, thread); \ + EXPECT(reader.ReadObject() == object); \ + delete message; \ + } + TEST_CASE(SerializeSingletons) { - // Write snapshot with object content. - uint8_t* buffer; - MessageWriter writer(&buffer, &malloc_allocator, &malloc_deallocator, true); - writer.WriteObject(Object::class_class()); - writer.WriteObject(Object::type_arguments_class()); - writer.WriteObject(Object::function_class()); - writer.WriteObject(Object::field_class()); - writer.WriteObject(Object::token_stream_class()); - writer.WriteObject(Object::script_class()); - writer.WriteObject(Object::library_class()); - writer.WriteObject(Object::code_class()); - writer.WriteObject(Object::instructions_class()); - writer.WriteObject(Object::pc_descriptors_class()); - writer.WriteObject(Object::exception_handlers_class()); - writer.WriteObject(Object::context_class()); - writer.WriteObject(Object::context_scope_class()); - intptr_t buffer_len = writer.BytesWritten(); - - // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); - EXPECT(Object::class_class() == reader.ReadObject()); - EXPECT(Object::type_arguments_class() == reader.ReadObject()); - EXPECT(Object::function_class() == reader.ReadObject()); - EXPECT(Object::field_class() == reader.ReadObject()); - EXPECT(Object::token_stream_class() == reader.ReadObject()); - EXPECT(Object::script_class() == reader.ReadObject()); - EXPECT(Object::library_class() == reader.ReadObject()); - EXPECT(Object::code_class() == reader.ReadObject()); - EXPECT(Object::instructions_class() == reader.ReadObject()); - EXPECT(Object::pc_descriptors_class() == reader.ReadObject()); - EXPECT(Object::exception_handlers_class() == reader.ReadObject()); - EXPECT(Object::context_class() == reader.ReadObject()); - EXPECT(Object::context_scope_class() == reader.ReadObject()); - - free(buffer); + TEST_ROUND_TRIP_IDENTICAL(Object::class_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::type_arguments_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::function_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::field_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::token_stream_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::script_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::library_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::code_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::instructions_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::pc_descriptors_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::exception_handlers_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::context_class()); + TEST_ROUND_TRIP_IDENTICAL(Object::context_scope_class()); } static void TestString(const char* cstr) { @@ -532,24 +514,24 @@ static void TestString(const char* cstr) { EXPECT(Utf8::IsValid(reinterpret_cast(cstr), strlen(cstr))); // Write snapshot with object content. String& str = String::Handle(String::New(cstr)); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(str); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(str, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); String& serialized_str = String::Handle(); serialized_str ^= reader.ReadObject(); EXPECT(str.Equals(serialized_str)); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kString, root->type); EXPECT_STREQ(cstr, root->value.as_string); CheckEncodeDecodeMessage(root); + delete message; } TEST_CASE(SerializeString) { @@ -576,20 +558,19 @@ TEST_CASE(SerializeArray) { smi ^= Smi::New(i); array.SetAt(i, smi); } - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(array); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); Array& serialized_array = Array::Handle(); serialized_array ^= reader.ReadObject(); EXPECT(array.CanonicalizeEquals(serialized_array)); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -599,6 +580,8 @@ TEST_CASE(SerializeArray) { EXPECT_EQ(i, element->value.as_int32); } CheckEncodeDecodeMessage(root); + + delete message; } TEST_CASE(SerializeArrayWithTypeArgument) { @@ -612,20 +595,19 @@ TEST_CASE(SerializeArrayWithTypeArgument) { smi ^= Smi::New(i); array.SetAt(i, smi); } - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(array); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); Array& serialized_array = Array::Handle(); serialized_array ^= reader.ReadObject(); EXPECT(array.CanonicalizeEquals(serialized_array)); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -635,6 +617,8 @@ TEST_CASE(SerializeArrayWithTypeArgument) { EXPECT_EQ(i, element->value.as_int32); } CheckEncodeDecodeMessage(root); + + delete message; } TEST_CASE(FailSerializeLargeArray) { @@ -688,25 +672,26 @@ TEST_CASE(SerializeEmptyArray) { // Write snapshot with object content. const int kArrayLength = 0; Array& array = Array::Handle(Array::New(kArrayLength)); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(array); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); Array& serialized_array = Array::Handle(); serialized_array ^= reader.ReadObject(); EXPECT(array.CanonicalizeEquals(serialized_array)); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); EXPECT(root->value.as_array.values == NULL); CheckEncodeDecodeMessage(root); + + delete message; } TEST_CASE(SerializeByteArray) { @@ -717,20 +702,19 @@ TEST_CASE(SerializeByteArray) { for (int i = 0; i < kTypedDataLength; i++) { typed_data.SetUint8(i, i); } - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(typed_data); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(typed_data, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); TypedData& serialized_typed_data = TypedData::Handle(); serialized_typed_data ^= reader.ReadObject(); EXPECT(serialized_typed_data.IsTypedData()); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kTypedData, root->type); EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length); @@ -738,6 +722,8 @@ TEST_CASE(SerializeByteArray) { EXPECT(root->value.as_typed_data.values[i] == i); } CheckEncodeDecodeMessage(root); + + delete message; } #define TEST_TYPED_ARRAY(darttype, ctype) \ @@ -750,17 +736,17 @@ TEST_CASE(SerializeByteArray) { for (int i = 0; i < kArrayLength; i++) { \ array.Set##darttype((i * scale), i); \ } \ - uint8_t* buffer; \ - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); \ - writer.WriteMessage(array); \ - intptr_t buffer_len = writer.BytesWritten(); \ - MessageSnapshotReader reader(buffer, buffer_len, thread); \ + MessageWriter writer(true); \ + Message* message = \ + writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority); \ + MessageSnapshotReader reader(message, thread); \ TypedData& serialized_array = TypedData::Handle(); \ serialized_array ^= reader.ReadObject(); \ for (int i = 0; i < kArrayLength; i++) { \ EXPECT_EQ(static_cast(i), \ serialized_array.Get##darttype(i* scale)); \ } \ + delete message; \ } #define TEST_EXTERNAL_TYPED_ARRAY(darttype, ctype) \ @@ -772,17 +758,17 @@ TEST_CASE(SerializeByteArray) { ExternalTypedData::New(kExternalTypedData##darttype##ArrayCid, \ reinterpret_cast(data), length)); \ intptr_t scale = array.ElementSizeInBytes(); \ - uint8_t* buffer; \ - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); \ - writer.WriteMessage(array); \ - intptr_t buffer_len = writer.BytesWritten(); \ - MessageSnapshotReader reader(buffer, buffer_len, thread); \ + MessageWriter writer(true); \ + Message* message = \ + writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority); \ + MessageSnapshotReader reader(message, thread); \ TypedData& serialized_array = TypedData::Handle(); \ serialized_array ^= reader.ReadObject(); \ for (int i = 0; i < length; i++) { \ EXPECT_EQ(static_cast(data[i]), \ serialized_array.Get##darttype(i* scale)); \ } \ + delete message; \ } TEST_CASE(SerializeTypedArray) { @@ -816,42 +802,41 @@ TEST_CASE(SerializeEmptyByteArray) { const int kTypedDataLength = 0; TypedData& typed_data = TypedData::Handle( TypedData::New(kTypedDataUint8ArrayCid, kTypedDataLength)); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); - writer.WriteMessage(typed_data); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(true); + Message* message = + writer.WriteMessage(typed_data, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot. - MessageSnapshotReader reader(buffer, buffer_len, thread); + MessageSnapshotReader reader(message, thread); TypedData& serialized_typed_data = TypedData::Handle(); serialized_typed_data ^= reader.ReadObject(); EXPECT(serialized_typed_data.IsTypedData()); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_EQ(Dart_CObject_kTypedData, root->type); EXPECT_EQ(Dart_TypedData_kUint8, root->value.as_typed_data.type); EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length); EXPECT(root->value.as_typed_data.values == NULL); CheckEncodeDecodeMessage(root); + + delete message; } class TestSnapshotWriter : public SnapshotWriter { public: static const intptr_t kInitialSize = 64 * KB; - TestSnapshotWriter(uint8_t** buffer, ReAlloc alloc) + explicit TestSnapshotWriter(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); } ~TestSnapshotWriter() {} @@ -955,12 +940,11 @@ TEST_CASE(SerializeScript) { EXPECT(CompilerTest::TestCompileScript(lib, script)); // Write snapshot with script content. - uint8_t* buffer; - TestSnapshotWriter writer(&buffer, &malloc_allocator); + TestSnapshotWriter writer(&malloc_allocator); writer.WriteScript(script); // Read object back from the snapshot. - ScriptSnapshotReader reader(buffer, writer.BytesWritten(), thread); + ScriptSnapshotReader reader(writer.buffer(), writer.BytesWritten(), thread); Script& serialized_script = Script::Handle(zone); serialized_script ^= reader.ReadObject(); @@ -1002,7 +986,7 @@ TEST_CASE(SerializeScript) { // the same. GenerateSourceAndCheck(serialized_script); - free(buffer); + free(writer.buffer()); } #if !defined(PRODUCT) // Uses mirrors. @@ -1809,51 +1793,22 @@ VM_UNIT_TEST_CASE(MismatchedSnapshotKinds) { #endif // !PRODUCT -TEST_CASE(IntArrayMessage) { - StackZone zone(Thread::Current()); - uint8_t* buffer = NULL; - ApiMessageWriter writer(&buffer, &zone_allocator); - - static const int kArrayLength = 2; - intptr_t data[kArrayLength] = {1, 2}; - int len = kArrayLength; - writer.WriteMessage(len, data); - - // Read object back from the snapshot into a C structure. - ApiNativeScope scope; - ApiMessageReader api_reader(buffer, writer.BytesWritten()); - Dart_CObject* root = api_reader.ReadMessage(); - EXPECT_EQ(Dart_CObject_kArray, root->type); - EXPECT_EQ(kArrayLength, root->value.as_array.length); - for (int i = 0; i < kArrayLength; i++) { - Dart_CObject* element = root->value.as_array.values[i]; - EXPECT_EQ(Dart_CObject_kInt32, element->type); - EXPECT_EQ(i + 1, element->value.as_int32); - } - CheckEncodeDecodeMessage(root); -} - // Helper function to call a top level Dart function and serialize the result. -static uint8_t* GetSerialized(Dart_Handle lib, - const char* dart_function, - intptr_t* buffer_len) { +static Message* GetSerialized(Dart_Handle lib, const char* dart_function) { Dart_Handle result; result = Dart_Invoke(lib, NewString(dart_function), 0, NULL); EXPECT_VALID(result); Object& obj = Object::Handle(Api::UnwrapHandle(result)); // Serialize the object into a message. - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, false); - writer.WriteMessage(obj); - *buffer_len = writer.BytesWritten(); - return buffer; + MessageWriter writer(false); + return writer.WriteMessage(obj, ILLEGAL_PORT, Message::kNormalPriority); } // Helper function to deserialize the result into a Dart_CObject structure. -static Dart_CObject* GetDeserialized(uint8_t* buffer, intptr_t buffer_len) { +static Dart_CObject* GetDeserialized(Message* message) { // Read object back from the snapshot into a C structure. - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); return api_reader.ReadMessage(); } @@ -1861,36 +1816,38 @@ static void CheckString(Dart_Handle dart_string, const char* expected) { StackZone zone(Thread::Current()); String& str = String::Handle(); str ^= Api::UnwrapHandle(dart_string); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, false); - writer.WriteMessage(str); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(false); + Message* message = + writer.WriteMessage(str, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kString, root->type); EXPECT_STREQ(expected, root->value.as_string); CheckEncodeDecodeMessage(root); + + delete message; } static void CheckStringInvalid(Dart_Handle dart_string) { StackZone zone(Thread::Current()); String& str = String::Handle(); str ^= Api::UnwrapHandle(dart_string); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, false); - writer.WriteMessage(str); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(false); + Message* message = + writer.WriteMessage(str, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kUnsupported, root->type); + + delete message; } VM_UNIT_TEST_CASE(DartGeneratedMessages) { @@ -2000,32 +1957,31 @@ VM_UNIT_TEST_CASE(DartGeneratedMessages) { StackZone zone(thread); Smi& smi = Smi::Handle(); smi ^= Api::UnwrapHandle(smi_result); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, false); - writer.WriteMessage(smi); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(false); + Message* message = + writer.WriteMessage(smi, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kInt32, root->type); EXPECT_EQ(42, root->value.as_int32); CheckEncodeDecodeMessage(root); + delete message; } if (!Bigint::IsDisabled()) { StackZone zone(thread); Bigint& bigint = Bigint::Handle(); bigint ^= Api::UnwrapHandle(bigint_result); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, false); - writer.WriteMessage(bigint); - intptr_t buffer_len = writer.BytesWritten(); + MessageWriter writer(false); + Message* message = + writer.WriteMessage(bigint, ILLEGAL_PORT, Message::kNormalPriority); // Read object back from the snapshot into a C structure. ApiNativeScope scope; - ApiMessageReader api_reader(buffer, buffer_len); + ApiMessageReader api_reader(message); Dart_CObject* root = api_reader.ReadMessage(); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kBigint, root->type); @@ -2033,6 +1989,7 @@ VM_UNIT_TEST_CASE(DartGeneratedMessages) { EXPECT_STREQ("-0x424242424242424242424242424242424242", hex_value); free(hex_value); CheckEncodeDecodeMessage(root); + delete message; } CheckString(ascii_string_result, "Hello, world!"); CheckString(non_ascii_string_result, "Blåbærgrød"); @@ -2088,12 +2045,11 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessages) { CHECK_API_SCOPE(thread); HANDLESCOPE(thread); StackZone zone(thread); - intptr_t buf_len = 0; { // Generate a list of nulls from Dart code. - uint8_t* buf = GetSerialized(lib, "getList", &buf_len); + Message* message = GetSerialized(lib, "getList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2101,12 +2057,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessages) { EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type); } CheckEncodeDecodeMessage(root); + delete message; } { // Generate a list of ints from Dart code. - uint8_t* buf = GetSerialized(lib, "getIntList", &buf_len); + Message* message = GetSerialized(lib, "getIntList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2115,12 +2072,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessages) { EXPECT_EQ(i, root->value.as_array.values[i]->value.as_int32); } CheckEncodeDecodeMessage(root); + delete message; } { // Generate a list of strings from Dart code. - uint8_t* buf = GetSerialized(lib, "getStringList", &buf_len); + Message* message = GetSerialized(lib, "getStringList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2130,12 +2088,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessages) { snprintf(buffer, sizeof(buffer), "%d", i); EXPECT_STREQ(buffer, root->value.as_array.values[i]->value.as_string); } + delete message; } { // Generate a list of objects of different types from Dart code. - uint8_t* buf = GetSerialized(lib, "getMixedList", &buf_len); + Message* message = GetSerialized(lib, "getMixedList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2154,6 +2113,7 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessages) { EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type); } } + delete message; } } Dart_ExitScope(); @@ -2212,12 +2172,11 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessages) { CHECK_API_SCOPE(thread); HANDLESCOPE(thread); StackZone zone(thread); - intptr_t buf_len = 0; { // Generate a list of nulls from Dart code. - uint8_t* buf = GetSerialized(lib, "getList", &buf_len); + Message* message = GetSerialized(lib, "getList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2225,12 +2184,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessages) { EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type); } CheckEncodeDecodeMessage(root); + delete message; } { // Generate a list of ints from Dart code. - uint8_t* buf = GetSerialized(lib, "getIntList", &buf_len); + Message* message = GetSerialized(lib, "getIntList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2239,12 +2199,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessages) { EXPECT_EQ(i, root->value.as_array.values[i]->value.as_int32); } CheckEncodeDecodeMessage(root); + delete message; } { // Generate a list of strings from Dart code. - uint8_t* buf = GetSerialized(lib, "getStringList", &buf_len); + Message* message = GetSerialized(lib, "getStringList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2254,12 +2215,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessages) { snprintf(buffer, sizeof(buffer), "%d", i); EXPECT_STREQ(buffer, root->value.as_array.values[i]->value.as_string); } + delete message; } { // Generate a list of lists from Dart code. - uint8_t* buf = GetSerialized(lib, "getListList", &buf_len); + Message* message = GetSerialized(lib, "getListList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2273,12 +2235,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessages) { EXPECT_EQ(j, element->value.as_array.values[j]->value.as_int32); } } + delete message; } { // Generate a list of objects of different types from Dart code. - uint8_t* buf = GetSerialized(lib, "getMixedList", &buf_len); + Message* message = GetSerialized(lib, "getMixedList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2374,6 +2337,7 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessages) { EXPECT_EQ(Dart_CObject_kInt32, e->type); EXPECT_EQ(i + 1, e->value.as_int32); } + delete message; } } Dart_ExitScope(); @@ -2458,12 +2422,11 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { CHECK_API_SCOPE(thread); HANDLESCOPE(thread); StackZone zone(thread); - intptr_t buf_len = 0; { // Generate a list of strings from Dart code. - uint8_t* buf = GetSerialized(lib, "getStringList", &buf_len); + Message* message = GetSerialized(lib, "getStringList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2473,12 +2436,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { EXPECT_EQ(Dart_CObject_kString, element->type); EXPECT_STREQ("Hello, world!", element->value.as_string); } + delete message; } { // Generate a list of medium ints from Dart code. - uint8_t* buf = GetSerialized(lib, "getMintList", &buf_len); + Message* message = GetSerialized(lib, "getMintList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2488,12 +2452,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { EXPECT_EQ(Dart_CObject_kInt64, element->type); EXPECT_EQ(DART_INT64_C(0x7FFFFFFFFFFFFFFF), element->value.as_int64); } + delete message; } if (!Bigint::IsDisabled()) { // Generate a list of bigints from Dart code. - uint8_t* buf = GetSerialized(lib, "getBigintList", &buf_len); + Message* message = GetSerialized(lib, "getBigintList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2505,12 +2470,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { EXPECT_STREQ("0x1234567890123456789012345678901234567890", hex_value); free(hex_value); } + delete message; } { // Generate a list of doubles from Dart code. - uint8_t* buf = GetSerialized(lib, "getDoubleList", &buf_len); + Message* message = GetSerialized(lib, "getDoubleList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2524,12 +2490,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { EXPECT_EQ(Dart_CObject_kDouble, element->type); EXPECT_EQ(3.14, element->value.as_double); } + delete message; } { // Generate a list of Uint8Lists from Dart code. - uint8_t* buf = GetSerialized(lib, "getTypedDataList", &buf_len); + Message* message = GetSerialized(lib, "getTypedDataList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2540,12 +2507,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { EXPECT_EQ(Dart_TypedData_kUint8, element->value.as_typed_data.type); EXPECT_EQ(256, element->value.as_typed_data.length); } + delete message; } { // Generate a list of Uint8List views from Dart code. - uint8_t* buf = GetSerialized(lib, "getTypedDataViewList", &buf_len); + Message* message = GetSerialized(lib, "getTypedDataViewList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2558,12 +2526,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { EXPECT_EQ(1, element->value.as_typed_data.values[0]); EXPECT_EQ(0, element->value.as_typed_data.values[1]); } + delete message; } { // Generate a list of objects of different types from Dart code. - uint8_t* buf = GetSerialized(lib, "getMixedList", &buf_len); + Message* message = GetSerialized(lib, "getMixedList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2586,12 +2555,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { EXPECT_STREQ(2.72, element->value.as_double); } } + delete message; } { // Generate a list of objects of different types from Dart code. - uint8_t* buf = GetSerialized(lib, "getSelfRefList", &buf_len); + Message* message = GetSerialized(lib, "getSelfRefList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2600,6 +2570,7 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { EXPECT_EQ(Dart_CObject_kArray, element->type); EXPECT_EQ(root, element); } + delete message; } } Dart_ExitScope(); @@ -2689,12 +2660,11 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) { CHECK_API_SCOPE(thread); HANDLESCOPE(thread); StackZone zone(thread); - intptr_t buf_len = 0; { // Generate a list of strings from Dart code. - uint8_t* buf = GetSerialized(lib, "getStringList", &buf_len); + Message* message = GetSerialized(lib, "getStringList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2704,12 +2674,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) { EXPECT_EQ(Dart_CObject_kString, element->type); EXPECT_STREQ("Hello, world!", element->value.as_string); } + delete message; } { // Generate a list of medium ints from Dart code. - uint8_t* buf = GetSerialized(lib, "getMintList", &buf_len); + Message* message = GetSerialized(lib, "getMintList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2719,12 +2690,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) { EXPECT_EQ(Dart_CObject_kInt64, element->type); EXPECT_EQ(DART_INT64_C(0x7FFFFFFFFFFFFFFF), element->value.as_int64); } + delete message; } if (!Bigint::IsDisabled()) { // Generate a list of bigints from Dart code. - uint8_t* buf = GetSerialized(lib, "getBigintList", &buf_len); + Message* message = GetSerialized(lib, "getBigintList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2736,12 +2708,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) { EXPECT_STREQ("0x1234567890123456789012345678901234567890", hex_value); free(hex_value); } + delete message; } { // Generate a list of doubles from Dart code. - uint8_t* buf = GetSerialized(lib, "getDoubleList", &buf_len); + Message* message = GetSerialized(lib, "getDoubleList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2756,12 +2729,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) { EXPECT_EQ(Dart_CObject_kDouble, element->type); EXPECT_EQ(3.14, element->value.as_double); } + delete message; } { // Generate a list of Uint8Lists from Dart code. - uint8_t* buf = GetSerialized(lib, "getTypedDataList", &buf_len); + Message* message = GetSerialized(lib, "getTypedDataList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2772,12 +2746,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) { EXPECT_EQ(Dart_TypedData_kUint8, element->value.as_typed_data.type); EXPECT_EQ(256, element->value.as_typed_data.length); } + delete message; } { // Generate a list of Uint8List views from Dart code. - uint8_t* buf = GetSerialized(lib, "getTypedDataViewList", &buf_len); + Message* message = GetSerialized(lib, "getTypedDataViewList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2790,12 +2765,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) { EXPECT_EQ(1, element->value.as_typed_data.values[0]); EXPECT_EQ(0, element->value.as_typed_data.values[1]); } + delete message; } { // Generate a list of objects of different types from Dart code. - uint8_t* buf = GetSerialized(lib, "getMixedList", &buf_len); + Message* message = GetSerialized(lib, "getMixedList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2818,12 +2794,13 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) { EXPECT_STREQ(2.72, element->value.as_double); } } + delete message; } { // Generate a list of objects of different types from Dart code. - uint8_t* buf = GetSerialized(lib, "getSelfRefList", &buf_len); + Message* message = GetSerialized(lib, "getSelfRefList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); EXPECT_EQ(kArrayLength, root->value.as_array.length); @@ -2832,6 +2809,7 @@ VM_UNIT_TEST_CASE(DartGeneratedArrayLiteralMessagesWithBackref) { EXPECT_EQ(Dart_CObject_kArray, element->type); EXPECT_EQ(root, element); } + delete message; } } Dart_ExitScope(); @@ -2930,12 +2908,11 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithTypedData) { CHECK_API_SCOPE(thread); HANDLESCOPE(thread); StackZone zone(thread); - intptr_t buf_len = 0; { // Generate a list of Uint8Lists from Dart code. - uint8_t* buf = GetSerialized(lib, "getTypedDataList", &buf_len); + Message* message = GetSerialized(lib, "getTypedDataList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); struct { @@ -2956,12 +2933,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithTypedData) { i++; } EXPECT_EQ(i, root->value.as_array.length); + delete message; } { // Generate a list of Uint8List views from Dart code. - uint8_t* buf = GetSerialized(lib, "getTypedDataViewList", &buf_len); + Message* message = GetSerialized(lib, "getTypedDataViewList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); struct { @@ -2995,13 +2973,13 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithTypedData) { i++; } EXPECT_EQ(i, root->value.as_array.length); + delete message; } { // Generate a list of Uint8Lists from Dart code. - uint8_t* buf = - GetSerialized(lib, "getMultipleTypedDataViewList", &buf_len); + Message* message = GetSerialized(lib, "getMultipleTypedDataViewList"); ApiNativeScope scope; - Dart_CObject* root = GetDeserialized(buf, buf_len); + Dart_CObject* root = GetDeserialized(message); EXPECT_NOTNULL(root); EXPECT_EQ(Dart_CObject_kArray, root->type); struct { @@ -3026,6 +3004,7 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithTypedData) { i++; } EXPECT_EQ(i, root->value.as_array.length); + delete message; } } Dart_ExitScope(); @@ -3129,12 +3108,13 @@ VM_UNIT_TEST_CASE(PostCObject) { TEST_CASE(OmittedObjectEncodingLength) { StackZone zone(Thread::Current()); - uint8_t* buffer; - MessageWriter writer(&buffer, &zone_allocator, &zone_deallocator, true); + MessageWriter writer(true); writer.WriteInlinedObjectHeader(kOmittedObjectId); // For performance, we'd like single-byte headers when ids are omitted. // If this starts failing, consider renumbering the snapshot ids. EXPECT_EQ(1, writer.BytesWritten()); + + free(writer.buffer()); } } // namespace dart