[vm] Use std::unique_ptr with Message

Message is a C++ type with a simple ownership model appropriate for
std::unique_ptr. This CL applies the following changes:

1. All uses of "new Message(...)" are replaced with
"Message::New(...)", which is effectively
"std::make_unique<Message>(...)". (The latter was only added in C++14,
but Dart still compiles in C++11 mode.)

2. All owning Message* are replaced with std::unique_ptr<Message>. The
notable exception is MessageQueue, which still uses raw Message*
internally to simplify the linked list handling.

3. All "delete message;" statements are removed.

4. Uses of "NULL" replaced with "nullptr" as necessary.

Change-Id: I05b5804289f2a225bfa05d3c1631129358fed373
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101222
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Matthew Dempsky <mdempsky@google.com>
diff --git a/runtime/lib/developer.cc b/runtime/lib/developer.cc
index defe884..f1eab3a 100644
--- a/runtime/lib/developer.cc
+++ b/runtime/lib/developer.cc
@@ -130,8 +130,8 @@
 
 static void SendNull(const SendPort& port) {
   const Dart_Port destination_port_id = port.Id();
-  PortMap::PostMessage(new Message(destination_port_id, Object::null(),
-                                   Message::kNormalPriority));
+  PortMap::PostMessage(Message::New(destination_port_id, Object::null(),
+                                    Message::kNormalPriority));
 }
 
 DEFINE_NATIVE_ENTRY(Developer_getServerInfo, 0, 1) {
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 2171150..d666686 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -95,7 +95,7 @@
 
   if (ApiObjectConverter::CanConvert(obj.raw())) {
     PortMap::PostMessage(
-        new Message(destination_port_id, obj.raw(), Message::kNormalPriority));
+        Message::New(destination_port_id, obj.raw(), Message::kNormalPriority));
   } else {
     MessageWriter writer(can_send_any_object);
     // TODO(turnidge): Throw an exception when the return value is false?
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index b56a033..265ca29 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -656,13 +656,12 @@
   for (intptr_t i = 0; i < kLoopCount; i++) {
     StackZone zone(thread);
     MessageWriter writer(true);
-    Message* message = writer.WriteMessage(null_object, ILLEGAL_PORT,
-                                           Message::kNormalPriority);
+    std::unique_ptr<Message> message = writer.WriteMessage(
+        null_object, ILLEGAL_PORT, Message::kNormalPriority);
 
     // Read object back from the snapshot.
-    MessageSnapshotReader reader(message, thread);
+    MessageSnapshotReader reader(message.get(), thread);
     reader.ReadObject();
-    delete message;
   }
   timer.Stop();
   int64_t elapsed_time = timer.TotalElapsedTime();
@@ -680,13 +679,12 @@
   for (intptr_t i = 0; i < kLoopCount; i++) {
     StackZone zone(thread);
     MessageWriter writer(true);
-    Message* message =
+    std::unique_ptr<Message> message =
         writer.WriteMessage(smi_object, ILLEGAL_PORT, Message::kNormalPriority);
 
     // Read object back from the snapshot.
-    MessageSnapshotReader reader(message, thread);
+    MessageSnapshotReader reader(message.get(), thread);
     reader.ReadObject();
-    delete message;
   }
   timer.Stop();
   int64_t elapsed_time = timer.TotalElapsedTime();
@@ -706,13 +704,12 @@
   for (intptr_t i = 0; i < kLoopCount; i++) {
     StackZone zone(thread);
     MessageWriter writer(true);
-    Message* message = writer.WriteMessage(array_object, ILLEGAL_PORT,
-                                           Message::kNormalPriority);
+    std::unique_ptr<Message> message = writer.WriteMessage(
+        array_object, ILLEGAL_PORT, Message::kNormalPriority);
 
     // Read object back from the snapshot.
-    MessageSnapshotReader reader(message, thread);
+    MessageSnapshotReader reader(message.get(), thread);
     reader.ReadObject();
-    delete message;
   }
   timer.Stop();
   int64_t elapsed_time = timer.TotalElapsedTime();
@@ -741,13 +738,12 @@
   for (intptr_t i = 0; i < kLoopCount; i++) {
     StackZone zone(thread);
     MessageWriter writer(true);
-    Message* message =
+    std::unique_ptr<Message> message =
         writer.WriteMessage(map, ILLEGAL_PORT, Message::kNormalPriority);
 
     // Read object back from the snapshot.
-    MessageSnapshotReader reader(message, thread);
+    MessageSnapshotReader reader(message.get(), thread);
     reader.ReadObject();
-    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 9c336a8..7f7a646 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1778,7 +1778,7 @@
   RawObject* raw_obj = Api::UnwrapHandle(handle);
   if (ApiObjectConverter::CanConvert(raw_obj)) {
     return PortMap::PostMessage(
-        new Message(port_id, raw_obj, Message::kNormalPriority));
+        Message::New(port_id, raw_obj, Message::kNormalPriority));
   }
 
   const Object& object = Object::Handle(Z, raw_obj);
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 0b2a7d5..ee4aa1d 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -1132,14 +1132,15 @@
   return true;
 }
 
-Message* ApiMessageWriter::WriteCMessage(Dart_CObject* object,
-                                         Dart_Port dest_port,
-                                         Message::Priority priority) {
+std::unique_ptr<Message> ApiMessageWriter::WriteCMessage(
+    Dart_CObject* object,
+    Dart_Port dest_port,
+    Message::Priority priority) {
   bool success = WriteCObject(object);
   if (!success) {
     UnmarkAllCObjects(object);
     free(buffer());
-    return NULL;
+    return nullptr;
   }
 
   // Write out all objects that were added to the forward list and have
@@ -1150,15 +1151,15 @@
     if (!success) {
       UnmarkAllCObjects(object);
       free(buffer());
-      return NULL;
+      return nullptr;
     }
   }
 
   UnmarkAllCObjects(object);
   MessageFinalizableData* finalizable_data = finalizable_data_;
   finalizable_data_ = NULL;
-  return new Message(dest_port, buffer(), BytesWritten(), finalizable_data,
-                     priority);
+  return Message::New(dest_port, buffer(), BytesWritten(), finalizable_data,
+                      priority);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index 082fc08..92a9a85 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -159,9 +159,9 @@
   ~ApiMessageWriter();
 
   // Writes a message with a single object.
-  Message* WriteCMessage(Dart_CObject* object,
-                         Dart_Port dest_port,
-                         Message::Priority priority);
+  std::unique_ptr<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 05c4dfc..49810ef 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -103,9 +103,10 @@
 };
 #endif
 
-static Message* SerializeMessage(Dart_Port dest_port, const Instance& obj) {
+static std::unique_ptr<Message> SerializeMessage(Dart_Port dest_port,
+                                                 const Instance& obj) {
   if (ApiObjectConverter::CanConvert(obj.raw())) {
-    return new Message(dest_port, obj.raw(), Message::kNormalPriority);
+    return Message::New(dest_port, obj.raw(), Message::kNormalPriority);
   } else {
     MessageWriter writer(false);
     return writer.WriteMessage(obj, dest_port, Message::kNormalPriority);
@@ -238,7 +239,7 @@
 
   const char* name() const;
   void MessageNotify(Message::Priority priority);
-  MessageStatus HandleMessage(Message* message);
+  MessageStatus HandleMessage(std::unique_ptr<Message> message);
 #ifndef PRODUCT
   void NotifyPauseOnStart();
   void NotifyPauseOnExit();
@@ -498,7 +499,7 @@
 }
 
 MessageHandler::MessageStatus IsolateMessageHandler::HandleMessage(
-    Message* message) {
+    std::unique_ptr<Message> message) {
   ASSERT(IsCurrentIsolate());
   Thread* thread = Thread::Current();
   StackZone stack_zone(thread);
@@ -520,16 +521,13 @@
   if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) {
     msg_handler = DartLibraryCalls::LookupHandler(message->dest_port());
     if (msg_handler.IsError()) {
-      delete message;
       return ProcessUnhandledException(Error::Cast(msg_handler));
     }
     if (msg_handler.IsNull()) {
       // If the port has been closed then the message will be dropped at this
       // point. Make sure to post to the delivery failure port in that case.
       if (message->RedirectToDeliveryFailurePort()) {
-        PortMap::PostMessage(message);
-      } else {
-        delete message;
+        PortMap::PostMessage(std::move(message));
       }
       return kOK;
     }
@@ -542,12 +540,11 @@
     // We should only be sending RawObjects that can be converted to CObjects.
     ASSERT(ApiObjectConverter::CanConvert(msg_obj.raw()));
   } else {
-    MessageSnapshotReader reader(message, thread);
+    MessageSnapshotReader reader(message.get(), thread);
     msg_obj = reader.ReadObject();
   }
   if (msg_obj.IsError()) {
     // An error occurred while reading the message.
-    delete message;
     return ProcessUnhandledException(Error::Cast(msg_obj));
   }
   if (!msg_obj.IsNull() && !msg_obj.IsInstance()) {
@@ -639,7 +636,6 @@
       ASSERT(result.IsNull());
     }
   }
-  delete message;
   return status;
 }
 
@@ -2491,9 +2487,9 @@
     element = Smi::New(Isolate::kBeforeNextEventAction);
     msg.SetAt(2, element);
     MessageWriter writer(false);
-    Message* message =
+    std::unique_ptr<Message> message =
         writer.WriteMessage(msg, main_port(), Message::kOOBPriority);
-    bool posted = PortMap::PostMessage(message);
+    bool posted = PortMap::PostMessage(std::move(message));
     ASSERT(posted);
   }
 }
@@ -2744,12 +2740,12 @@
 
   {
     ApiMessageWriter writer;
-    Message* message =
+    std::unique_ptr<Message> message =
         writer.WriteCMessage(&kill_msg, main_port(), Message::kOOBPriority);
     ASSERT(message != nullptr);
 
     // Post the message at the given port.
-    bool success = PortMap::PostMessage(message);
+    bool success = PortMap::PostMessage(std::move(message));
     ASSERT(success);
   }
 }
@@ -3027,8 +3023,6 @@
   delete[] class_name_;
   delete[] function_name_;
   delete[] debug_name_;
-  delete serialized_args_;
-  delete serialized_message_;
 }
 
 RawObject* IsolateSpawnState::ResolveFunction() {
@@ -3109,11 +3103,11 @@
 }
 
 RawInstance* IsolateSpawnState::BuildArgs(Thread* thread) {
-  return DeserializeMessage(thread, serialized_args_);
+  return DeserializeMessage(thread, serialized_args_.get());
 }
 
 RawInstance* IsolateSpawnState::BuildMessage(Thread* thread) {
-  return DeserializeMessage(thread, serialized_message_);
+  return DeserializeMessage(thread, serialized_message_.get());
 }
 
 void IsolateSpawnState::DecrementSpawnCount() {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index c69042b..f0484c9 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -9,6 +9,8 @@
 #error "Should not include runtime"
 #endif
 
+#include <memory>
+
 #include "include/dart_api.h"
 #include "platform/assert.h"
 #include "platform/atomic.h"
@@ -1197,8 +1199,8 @@
   const char* class_name_;
   const char* function_name_;
   const char* debug_name_;
-  Message* serialized_args_;
-  Message* serialized_message_;
+  std::unique_ptr<Message> serialized_args_;
+  std::unique_ptr<Message> serialized_message_;
 
   // This counter tracks the number of outstanding calls to spawn by the parent
   // isolate.
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 31adba4..05f474e 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -179,7 +179,7 @@
 
 void JSONStream::PostNullReply(Dart_Port port) {
   PortMap::PostMessage(
-      new Message(port, Object::null(), Message::kNormalPriority));
+      Message::New(port, Object::null(), Message::kNormalPriority));
 }
 
 static void Finalizer(void* isolate_callback_data,
diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
index 985c5b5..4d08a30 100644
--- a/runtime/vm/message.cc
+++ b/runtime/vm/message.cc
@@ -93,7 +93,10 @@
   ASSERT(head_ == NULL);
 }
 
-void MessageQueue::Enqueue(Message* msg, bool before_events) {
+void MessageQueue::Enqueue(std::unique_ptr<Message> msg0, bool before_events) {
+  // TODO(mdempsky): Use unique_ptr internally?
+  Message* msg = msg0.release();
+
   // Make sure messages are not reused.
   ASSERT(msg->next_ == NULL);
   if (head_ == NULL) {
@@ -134,34 +137,32 @@
   }
 }
 
-Message* MessageQueue::Dequeue() {
+std::unique_ptr<Message> MessageQueue::Dequeue() {
   Message* result = head_;
-  if (result != NULL) {
+  if (result != nullptr) {
     head_ = result->next_;
     // The following update to tail_ is not strictly needed.
-    if (head_ == NULL) {
-      tail_ = NULL;
+    if (head_ == nullptr) {
+      tail_ = nullptr;
     }
 #if defined(DEBUG)
     result->next_ = result;  // Make sure to trigger ASSERT in Enqueue.
 #endif                       // DEBUG
-    return result;
+    return std::unique_ptr<Message>(result);
   }
-  return NULL;
+  return nullptr;
 }
 
 void MessageQueue::Clear() {
-  Message* cur = head_;
-  head_ = NULL;
-  tail_ = NULL;
-  while (cur != NULL) {
-    Message* next = cur->next_;
+  std::unique_ptr<Message> cur(head_);
+  head_ = nullptr;
+  tail_ = nullptr;
+  while (cur != nullptr) {
+    std::unique_ptr<Message> next(cur->next_);
     if (cur->RedirectToDeliveryFailurePort()) {
-      PortMap::PostMessage(cur);
-    } else {
-      delete cur;
+      PortMap::PostMessage(std::move(cur));
     }
-    cur = next;
+    cur = std::move(next);
   }
 }
 
diff --git a/runtime/vm/message.h b/runtime/vm/message.h
index 51ff2551..4bf2303 100644
--- a/runtime/vm/message.h
+++ b/runtime/vm/message.h
@@ -5,6 +5,8 @@
 #ifndef RUNTIME_VM_MESSAGE_H_
 #define RUNTIME_VM_MESSAGE_H_
 
+#include <memory>
+
 #include "platform/assert.h"
 #include "vm/allocation.h"
 #include "vm/finalizable_data.h"
@@ -61,6 +63,11 @@
 
   ~Message();
 
+  template <typename... Args>
+  static std::unique_ptr<Message> New(Args&&... args) {
+    return std::unique_ptr<Message>(new Message(std::forward<Args>(args)...));
+  }
+
   Dart_Port dest_port() const { return dest_port_; }
 
   uint8_t* snapshot() const {
@@ -114,11 +121,11 @@
   MessageQueue();
   ~MessageQueue();
 
-  void Enqueue(Message* msg, bool before_events);
+  void Enqueue(std::unique_ptr<Message> msg, bool before_events);
 
   // Gets the next message from the message queue or NULL if no
   // message is available.  This function will not block.
-  Message* Dequeue();
+  std::unique_ptr<Message> Dequeue();
 
   bool IsEmpty() { return head_ == NULL; }
 
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index c1ae538..da32e9a 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -121,7 +121,8 @@
   ASSERT(task_running);
 }
 
-void MessageHandler::PostMessage(Message* message, bool before_events) {
+void MessageHandler::PostMessage(std::unique_ptr<Message> message,
+                                 bool before_events) {
   Message::Priority saved_priority;
   bool task_running = true;
   {
@@ -149,14 +150,13 @@
 
     saved_priority = message->priority();
     if (message->IsOOB()) {
-      oob_queue_->Enqueue(message, before_events);
+      oob_queue_->Enqueue(std::move(message), before_events);
     } else {
-      queue_->Enqueue(message, before_events);
+      queue_->Enqueue(std::move(message), before_events);
     }
     if (paused_for_messages_) {
       ml.Notify();
     }
-    message = NULL;  // Do not access message.  May have been deleted.
 
     if ((pool_ != NULL) && (task_ == NULL)) {
       ASSERT(!delete_me_);
@@ -170,10 +170,11 @@
   MessageNotify(saved_priority);
 }
 
-Message* MessageHandler::DequeueMessage(Message::Priority min_priority) {
+std::unique_ptr<Message> MessageHandler::DequeueMessage(
+    Message::Priority min_priority) {
   // TODO(turnidge): Add assert that monitor_ is held here.
-  Message* message = oob_queue_->Dequeue();
-  if ((message == NULL) && (min_priority < Message::kOOBPriority)) {
+  std::unique_ptr<Message> message = oob_queue_->Dequeue();
+  if ((message == nullptr) && (min_priority < Message::kOOBPriority)) {
     message = queue_->Dequeue();
   }
   return message;
@@ -196,8 +197,8 @@
   Message::Priority min_priority =
       ((allow_normal_messages && !paused()) ? Message::kNormalPriority
                                             : Message::kOOBPriority);
-  Message* message = DequeueMessage(min_priority);
-  while (message != NULL) {
+  std::unique_ptr<Message> message = DequeueMessage(min_priority);
+  while (message != nullptr) {
     intptr_t message_len = message->Size();
     if (FLAG_trace_isolates) {
       OS::PrintErr(
@@ -214,11 +215,10 @@
     ml->Exit();
     Message::Priority saved_priority = message->priority();
     Dart_Port saved_dest_port = message->dest_port();
-    MessageStatus status = HandleMessage(message);
+    MessageStatus status = HandleMessage(std::move(message));
     if (status > max_status) {
       max_status = status;
     }
-    message = NULL;  // May be deleted by now.
     ml->Enter();
     if (FLAG_trace_isolates) {
       OS::PrintErr(
diff --git a/runtime/vm/message_handler.h b/runtime/vm/message_handler.h
index 46dd862..babc541 100644
--- a/runtime/vm/message_handler.h
+++ b/runtime/vm/message_handler.h
@@ -5,6 +5,8 @@
 #ifndef RUNTIME_VM_MESSAGE_HANDLER_H_
 #define RUNTIME_VM_MESSAGE_HANDLER_H_
 
+#include <memory>
+
 #include "vm/isolate.h"
 #include "vm/lockers.h"
 #include "vm/message.h"
@@ -168,7 +170,8 @@
   // Posts a message on this handler's message queue.
   // If before_events is true, then the message is enqueued before any pending
   // events, but after any pending isolate library events.
-  void PostMessage(Message* message, bool before_events = false);
+  void PostMessage(std::unique_ptr<Message> message,
+                   bool before_events = false);
 
   // Notifies this handler that a port is being closed.
   void ClosePort(Dart_Port port);
@@ -195,7 +198,7 @@
   // Handles a single message.  Provided by subclass.
   //
   // Returns true on success.
-  virtual MessageStatus HandleMessage(Message* message) = 0;
+  virtual MessageStatus HandleMessage(std::unique_ptr<Message> message) = 0;
 
   virtual void NotifyPauseOnStart() {}
   virtual void NotifyPauseOnExit() {}
@@ -229,7 +232,7 @@
 
   // Dequeue the next message.  Prefer messages from the oob_queue_ to
   // messages from the queue_.
-  Message* DequeueMessage(Message::Priority min_priority);
+  std::unique_ptr<Message> DequeueMessage(Message::Priority min_priority);
 
   void ClearOOBQueue();
 
diff --git a/runtime/vm/message_handler_test.cc b/runtime/vm/message_handler_test.cc
index 0677178..76c46a1 100644
--- a/runtime/vm/message_handler_test.cc
+++ b/runtime/vm/message_handler_test.cc
@@ -13,7 +13,9 @@
   explicit MessageHandlerTestPeer(MessageHandler* handler)
       : handler_(handler) {}
 
-  void PostMessage(Message* message) { handler_->PostMessage(message); }
+  void PostMessage(std::unique_ptr<Message> message) {
+    handler_->PostMessage(std::move(message));
+  }
   void ClosePort(Dart_Port port) { handler_->ClosePort(port); }
   void CloseAllPorts() { handler_->CloseAllPorts(); }
 
@@ -47,11 +49,10 @@
 
   void MessageNotify(Message::Priority priority) { notify_count_++; }
 
-  MessageStatus HandleMessage(Message* message) {
+  MessageStatus HandleMessage(std::unique_ptr<Message> message) {
     // For testing purposes, keep a list of the ports
     // for all messages we receive.
     AddPortToBuffer(message->dest_port());
-    delete message;
     message_count_++;
     MessageStatus status = kOK;
     if (results_ != NULL) {
@@ -116,9 +117,10 @@
   return (reinterpret_cast<TestMessageHandler*>(data))->End();
 }
 
-static Message* BlankMessage(Dart_Port dest, Message::Priority priority) {
-  return new Message(dest, reinterpret_cast<uint8_t*>(malloc(1)), 1, NULL,
-                     priority);
+static std::unique_ptr<Message> BlankMessage(Dart_Port dest,
+                                             Message::Priority priority) {
+  return Message::New(dest, reinterpret_cast<uint8_t*>(malloc(1)), 1, nullptr,
+                      priority);
 }
 
 VM_UNIT_TEST_CASE(MessageHandler_PostMessage) {
@@ -127,28 +129,28 @@
   EXPECT_EQ(0, handler.notify_count());
 
   // Post a message.
-  Message* message = BlankMessage(1, Message::kNormalPriority);
-  handler_peer.PostMessage(message);
+  std::unique_ptr<Message> message = BlankMessage(1, Message::kNormalPriority);
+  Message* raw_message = message.get();
+  handler_peer.PostMessage(std::move(message));
 
   // The notify callback is called.
   EXPECT_EQ(1, handler.notify_count());
 
   // The message has been added to the correct queue.
-  EXPECT(message == handler_peer.queue()->Dequeue());
-  EXPECT(NULL == handler_peer.oob_queue()->Dequeue());
-  delete message;
+  EXPECT(raw_message == handler_peer.queue()->Dequeue().get());
+  EXPECT(nullptr == handler_peer.oob_queue()->Dequeue());
 
   // Post an oob message.
   message = BlankMessage(1, Message::kOOBPriority);
-  handler_peer.PostMessage(message);
+  raw_message = message.get();
+  handler_peer.PostMessage(std::move(message));
 
   // The notify callback is called.
   EXPECT_EQ(2, handler.notify_count());
 
   // The message has been added to the correct queue.
-  EXPECT(message == handler_peer.oob_queue()->Dequeue());
-  EXPECT(NULL == handler_peer.queue()->Dequeue());
-  delete message;
+  EXPECT(raw_message == handler_peer.oob_queue()->Dequeue().get());
+  EXPECT(nullptr == handler_peer.queue()->Dequeue());
 }
 
 VM_UNIT_TEST_CASE(MessageHandler_HasOOBMessages) {
@@ -158,8 +160,8 @@
   EXPECT(!handler.HasOOBMessages());
 
   // Post a normal message.
-  Message* message = BlankMessage(1, Message::kNormalPriority);
-  handler_peer.PostMessage(message);
+  std::unique_ptr<Message> message = BlankMessage(1, Message::kNormalPriority);
+  handler_peer.PostMessage(std::move(message));
   EXPECT(!handler.HasOOBMessages());
   {
     // Acquire ownership of message handler queues, verify one regular message.
@@ -169,7 +171,7 @@
 
   // Post an oob message.
   message = BlankMessage(1, Message::kOOBPriority);
-  handler_peer.PostMessage(message);
+  handler_peer.PostMessage(std::move(message));
   EXPECT(handler.HasOOBMessages());
   {
     // Acquire ownership of message handler queues, verify one regular and one
@@ -186,32 +188,31 @@
 VM_UNIT_TEST_CASE(MessageHandler_ClosePort) {
   TestMessageHandler handler;
   MessageHandlerTestPeer handler_peer(&handler);
-  Message* message1 = BlankMessage(1, Message::kNormalPriority);
-  handler_peer.PostMessage(message1);
-  Message* message2 = BlankMessage(2, Message::kNormalPriority);
-  handler_peer.PostMessage(message2);
+  std::unique_ptr<Message> message;
+  message = BlankMessage(1, Message::kNormalPriority);
+  Message* raw_message1 = message.get();
+  handler_peer.PostMessage(std::move(message));
+  message = BlankMessage(2, Message::kNormalPriority);
+  Message* raw_message2 = message.get();
+  handler_peer.PostMessage(std::move(message));
 
   handler_peer.ClosePort(1);
 
   // Closing the port does not drop the messages from the queue.
-  EXPECT(message1 == handler_peer.queue()->Dequeue());
-  EXPECT(message2 == handler_peer.queue()->Dequeue());
-  delete message1;
-  delete message2;
+  EXPECT(raw_message1 == handler_peer.queue()->Dequeue().get());
+  EXPECT(raw_message2 == handler_peer.queue()->Dequeue().get());
 }
 
 VM_UNIT_TEST_CASE(MessageHandler_CloseAllPorts) {
   TestMessageHandler handler;
   MessageHandlerTestPeer handler_peer(&handler);
-  Message* message1 = BlankMessage(1, Message::kNormalPriority);
-  handler_peer.PostMessage(message1);
-  Message* message2 = BlankMessage(2, Message::kNormalPriority);
-  handler_peer.PostMessage(message2);
+  handler_peer.PostMessage(BlankMessage(1, Message::kNormalPriority));
+  handler_peer.PostMessage(BlankMessage(2, Message::kNormalPriority));
 
   handler_peer.CloseAllPorts();
 
   // All messages are dropped from the queue.
-  EXPECT(NULL == handler_peer.queue()->Dequeue());
+  EXPECT(nullptr == handler_peer.queue()->Dequeue());
 }
 
 VM_UNIT_TEST_CASE(MessageHandler_HandleNextMessage) {
@@ -220,14 +221,10 @@
   Dart_Port port1 = PortMap::CreatePort(&handler);
   Dart_Port port2 = PortMap::CreatePort(&handler);
   Dart_Port port3 = PortMap::CreatePort(&handler);
-  Message* message1 = BlankMessage(port1, Message::kNormalPriority);
-  handler_peer.PostMessage(message1);
-  Message* oob_message1 = BlankMessage(port2, Message::kOOBPriority);
-  handler_peer.PostMessage(oob_message1);
-  Message* message2 = BlankMessage(port2, Message::kNormalPriority);
-  handler_peer.PostMessage(message2);
-  Message* oob_message2 = BlankMessage(port3, Message::kOOBPriority);
-  handler_peer.PostMessage(oob_message2);
+  handler_peer.PostMessage(BlankMessage(port1, Message::kNormalPriority));
+  handler_peer.PostMessage(BlankMessage(port2, Message::kOOBPriority));
+  handler_peer.PostMessage(BlankMessage(port2, Message::kNormalPriority));
+  handler_peer.PostMessage(BlankMessage(port3, Message::kOOBPriority));
 
   // We handle both oob messages and a single normal message.
   EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
@@ -250,12 +247,9 @@
   Dart_Port port1 = PortMap::CreatePort(&handler);
   Dart_Port port2 = PortMap::CreatePort(&handler);
   Dart_Port port3 = PortMap::CreatePort(&handler);
-  Message* message1 = BlankMessage(port1, Message::kNormalPriority);
-  handler_peer.PostMessage(message1);
-  Message* oob_message1 = BlankMessage(port2, Message::kOOBPriority);
-  handler_peer.PostMessage(oob_message1);
-  Message* oob_message2 = BlankMessage(port3, Message::kOOBPriority);
-  handler_peer.PostMessage(oob_message2);
+  handler_peer.PostMessage(BlankMessage(port1, Message::kNormalPriority));
+  handler_peer.PostMessage(BlankMessage(port2, Message::kOOBPriority));
+  handler_peer.PostMessage(BlankMessage(port3, Message::kOOBPriority));
 
   // When we get an error, we continue processing oob messages but
   // stop handling normal messages.
@@ -281,14 +275,10 @@
   Dart_Port port2 = PortMap::CreatePort(&handler);
   Dart_Port port3 = PortMap::CreatePort(&handler);
   Dart_Port port4 = PortMap::CreatePort(&handler);
-  Message* message1 = BlankMessage(port1, Message::kNormalPriority);
-  handler_peer.PostMessage(message1);
-  Message* oob_message1 = BlankMessage(port2, Message::kOOBPriority);
-  handler_peer.PostMessage(oob_message1);
-  Message* oob_message2 = BlankMessage(port3, Message::kOOBPriority);
-  handler_peer.PostMessage(oob_message2);
-  Message* oob_message3 = BlankMessage(port4, Message::kOOBPriority);
-  handler_peer.PostMessage(oob_message3);
+  handler_peer.PostMessage(BlankMessage(port1, Message::kNormalPriority));
+  handler_peer.PostMessage(BlankMessage(port2, Message::kOOBPriority));
+  handler_peer.PostMessage(BlankMessage(port3, Message::kOOBPriority));
+  handler_peer.PostMessage(BlankMessage(port4, Message::kOOBPriority));
 
   // When we get a shutdown message, we stop processing all messages.
   EXPECT_EQ(MessageHandler::kShutdown, handler.HandleNextMessage());
@@ -311,14 +301,10 @@
   Dart_Port port2 = PortMap::CreatePort(&handler);
   Dart_Port port3 = PortMap::CreatePort(&handler);
   Dart_Port port4 = PortMap::CreatePort(&handler);
-  Message* message1 = BlankMessage(port1, Message::kNormalPriority);
-  handler_peer.PostMessage(message1);
-  Message* message2 = BlankMessage(port2, Message::kNormalPriority);
-  handler_peer.PostMessage(message2);
-  Message* oob_message1 = BlankMessage(port3, Message::kOOBPriority);
-  handler_peer.PostMessage(oob_message1);
-  Message* oob_message2 = BlankMessage(port4, Message::kOOBPriority);
-  handler_peer.PostMessage(oob_message2);
+  handler_peer.PostMessage(BlankMessage(port1, Message::kNormalPriority));
+  handler_peer.PostMessage(BlankMessage(port2, Message::kNormalPriority));
+  handler_peer.PostMessage(BlankMessage(port3, Message::kOOBPriority));
+  handler_peer.PostMessage(BlankMessage(port4, Message::kOOBPriority));
 
   // We handle both oob messages but no normal messages.
   EXPECT_EQ(MessageHandler::kOK, handler.HandleOOBMessages());
@@ -340,8 +326,8 @@
   MessageHandler* handler = info->handler;
   MessageHandlerTestPeer handler_peer(handler);
   for (int i = 0; i < info->count; i++) {
-    Message* message = BlankMessage(info->ports[i], Message::kNormalPriority);
-    handler_peer.PostMessage(message);
+    handler_peer.PostMessage(
+        BlankMessage(info->ports[i], Message::kNormalPriority));
   }
 }
 
@@ -358,8 +344,7 @@
   handler.Run(&pool, TestStartFunction, TestEndFunction,
               reinterpret_cast<uword>(&handler));
   Dart_Port port = PortMap::CreatePort(&handler);
-  Message* message = BlankMessage(port, Message::kNormalPriority);
-  handler_peer.PostMessage(message);
+  handler_peer.PostMessage(BlankMessage(port, Message::kNormalPriority));
 
   // Wait for the first message to be handled.
   while (sleep < kMaxSleep && handler.message_count() < 1) {
@@ -373,7 +358,7 @@
   EXPECT_EQ(port, handler_ports[0]);
 
   // Start a thread which sends more messages.
-  Dart_Port* ports = new Dart_Port[10];
+  Dart_Port ports[10];
   for (int i = 0; i < 10; i++) {
     ports[i] = PortMap::CreatePort(&handler);
   }
@@ -396,7 +381,6 @@
   }
   handler_peer.decrement_live_ports();
   EXPECT(!handler.HasLivePorts());
-  delete[] ports;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/message_test.cc b/runtime/vm/message_test.cc
index c07f78c..f580820 100644
--- a/runtime/vm/message_test.cc
+++ b/runtime/vm/message_test.cc
@@ -29,9 +29,11 @@
   const char* str6 = "msg6";
 
   // Add two messages.
-  Message* msg1 = new Message(port, AllocMsg(str1), strlen(str1) + 1, NULL,
-                              Message::kNormalPriority);
-  queue.Enqueue(msg1, false);
+  std::unique_ptr<Message> msg =
+      Message::New(port, AllocMsg(str1), strlen(str1) + 1, nullptr,
+                   Message::kNormalPriority);
+  Message* msg1 = msg.get();
+  queue.Enqueue(std::move(msg), false);
   EXPECT(queue.Length() == 1);
   EXPECT(!queue.IsEmpty());
   it.Reset(&queue);
@@ -39,9 +41,10 @@
   EXPECT(it.Next() == msg1);
   EXPECT(!it.HasNext());
 
-  Message* msg2 = new Message(port, AllocMsg(str2), strlen(str2) + 1, NULL,
-                              Message::kNormalPriority);
-  queue.Enqueue(msg2, false);
+  msg = Message::New(port, AllocMsg(str2), strlen(str2) + 1, nullptr,
+                     Message::kNormalPriority);
+  Message* msg2 = msg.get();
+  queue.Enqueue(std::move(msg), false);
   EXPECT(queue.Length() == 2);
   EXPECT(!queue.IsEmpty());
   it.Reset(&queue);
@@ -59,8 +62,8 @@
   EXPECT(queue.FindMessageById(0x1) == NULL);
 
   // Remove message 1
-  Message* msg = queue.Dequeue();
-  EXPECT(msg != NULL);
+  msg = queue.Dequeue();
+  EXPECT(msg != nullptr);
   EXPECT_STREQ(str1, reinterpret_cast<char*>(msg->snapshot()));
   EXPECT(!queue.IsEmpty());
 
@@ -70,56 +73,49 @@
 
   // Remove message 2
   msg = queue.Dequeue();
-  EXPECT(msg != NULL);
+  EXPECT(msg != nullptr);
   EXPECT_STREQ(str2, reinterpret_cast<char*>(msg->snapshot()));
   EXPECT(queue.IsEmpty());
 
-  Message* msg3 = new Message(Message::kIllegalPort, AllocMsg(str3),
-                              strlen(str3) + 1, NULL, Message::kNormalPriority);
-  queue.Enqueue(msg3, true);
+  msg = Message::New(Message::kIllegalPort, AllocMsg(str3), strlen(str3) + 1,
+                     nullptr, Message::kNormalPriority);
+  queue.Enqueue(std::move(msg), true);
   EXPECT(!queue.IsEmpty());
 
-  Message* msg4 = new Message(Message::kIllegalPort, AllocMsg(str4),
-                              strlen(str4) + 1, NULL, Message::kNormalPriority);
-  queue.Enqueue(msg4, true);
+  msg = Message::New(Message::kIllegalPort, AllocMsg(str4), strlen(str4) + 1,
+                     nullptr, Message::kNormalPriority);
+  queue.Enqueue(std::move(msg), true);
   EXPECT(!queue.IsEmpty());
 
-  Message* msg5 = new Message(port, AllocMsg(str5), strlen(str5) + 1, NULL,
-                              Message::kNormalPriority);
-  queue.Enqueue(msg5, false);
+  msg = Message::New(port, AllocMsg(str5), strlen(str5) + 1, nullptr,
+                     Message::kNormalPriority);
+  queue.Enqueue(std::move(msg), false);
   EXPECT(!queue.IsEmpty());
 
-  Message* msg6 = new Message(Message::kIllegalPort, AllocMsg(str6),
-                              strlen(str6) + 1, NULL, Message::kNormalPriority);
-  queue.Enqueue(msg6, true);
+  msg = Message::New(Message::kIllegalPort, AllocMsg(str6), strlen(str6) + 1,
+                     nullptr, Message::kNormalPriority);
+  queue.Enqueue(std::move(msg), true);
   EXPECT(!queue.IsEmpty());
 
   msg = queue.Dequeue();
-  EXPECT(msg != NULL);
+  EXPECT(msg != nullptr);
   EXPECT_STREQ(str3, reinterpret_cast<char*>(msg->snapshot()));
   EXPECT(!queue.IsEmpty());
 
   msg = queue.Dequeue();
-  EXPECT(msg != NULL);
+  EXPECT(msg != nullptr);
   EXPECT_STREQ(str4, reinterpret_cast<char*>(msg->snapshot()));
   EXPECT(!queue.IsEmpty());
 
   msg = queue.Dequeue();
-  EXPECT(msg != NULL);
+  EXPECT(msg != nullptr);
   EXPECT_STREQ(str6, reinterpret_cast<char*>(msg->snapshot()));
   EXPECT(!queue.IsEmpty());
 
   msg = queue.Dequeue();
-  EXPECT(msg != NULL);
+  EXPECT(msg != nullptr);
   EXPECT_STREQ(str5, reinterpret_cast<char*>(msg->snapshot()));
   EXPECT(queue.IsEmpty());
-
-  delete msg1;
-  delete msg2;
-  delete msg3;
-  delete msg4;
-  delete msg5;
-  delete msg6;
 }
 
 TEST_CASE(MessageQueue_Clear) {
@@ -131,18 +127,17 @@
   const char* str2 = "msg2";
 
   // Add two messages.
-  Message* msg1 = new Message(port1, AllocMsg(str1), strlen(str1) + 1, NULL,
-                              Message::kNormalPriority);
-  queue.Enqueue(msg1, false);
-  Message* msg2 = new Message(port2, AllocMsg(str2), strlen(str2) + 1, NULL,
-                              Message::kNormalPriority);
-  queue.Enqueue(msg2, false);
+  std::unique_ptr<Message> msg;
+  msg = Message::New(port1, AllocMsg(str1), strlen(str1) + 1, nullptr,
+                     Message::kNormalPriority);
+  queue.Enqueue(std::move(msg), false);
+  msg = Message::New(port2, AllocMsg(str2), strlen(str2) + 1, nullptr,
+                     Message::kNormalPriority);
+  queue.Enqueue(std::move(msg), false);
 
   EXPECT(!queue.IsEmpty());
   queue.Clear();
   EXPECT(queue.IsEmpty());
-
-  // msg1 and msg2 already delete by FlushAll.
 }
 
 }  // namespace dart
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index 92192fd..9bf957d 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -41,15 +41,15 @@
 
 static bool PostCObjectHelper(Dart_Port port_id, Dart_CObject* message) {
   ApiMessageWriter writer;
-  Message* msg =
+  std::unique_ptr<Message> msg =
       writer.WriteCMessage(message, port_id, Message::kNormalPriority);
 
-  if (msg == NULL) {
+  if (msg == nullptr) {
     return false;
   }
 
   // Post the message at the given port.
-  return PortMap::PostMessage(msg);
+  return PortMap::PostMessage(std::move(msg));
 }
 
 DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) {
@@ -59,7 +59,7 @@
 DART_EXPORT bool Dart_PostInteger(Dart_Port port_id, int64_t message) {
   if (Smi::IsValid(message)) {
     return PortMap::PostMessage(
-        new Message(port_id, Smi::New(message), Message::kNormalPriority));
+        Message::New(port_id, Smi::New(message), Message::kNormalPriority));
   }
   Dart_CObject cobj;
   cobj.type = Dart_CObject_kInt64;
diff --git a/runtime/vm/native_message_handler.cc b/runtime/vm/native_message_handler.cc
index a09d77c..009111c 100644
--- a/runtime/vm/native_message_handler.cc
+++ b/runtime/vm/native_message_handler.cc
@@ -26,7 +26,7 @@
 #endif
 
 MessageHandler::MessageStatus NativeMessageHandler::HandleMessage(
-    Message* message) {
+    std::unique_ptr<Message> message) {
   if (message->IsOOB()) {
     // We currently do not use OOB messages for native ports.
     UNREACHABLE();
@@ -36,10 +36,9 @@
   // zone associated with this scope.
   ApiNativeScope scope;
   Dart_CObject* object;
-  ApiMessageReader reader(message);
+  ApiMessageReader reader(message.get());
   object = reader.ReadMessage();
   (*func())(message->dest_port(), object);
-  delete message;
   return kOK;
 }
 
diff --git a/runtime/vm/native_message_handler.h b/runtime/vm/native_message_handler.h
index 7133662..82a0b98 100644
--- a/runtime/vm/native_message_handler.h
+++ b/runtime/vm/native_message_handler.h
@@ -21,7 +21,7 @@
   const char* name() const { return name_; }
   Dart_NativeMessageHandler func() const { return func_; }
 
-  MessageStatus HandleMessage(Message* message);
+  MessageStatus HandleMessage(std::unique_ptr<Message> message);
 
 #if defined(DEBUG)
   // Check that it is safe to access this handler.
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 31ab676..4ad4340 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -236,11 +236,11 @@
   handler->CloseAllPorts();
 }
 
-bool PortMap::PostMessage(Message* message, bool before_events) {
+bool PortMap::PostMessage(std::unique_ptr<Message> message,
+                          bool before_events) {
   MutexLocker ml(mutex_);
   intptr_t index = FindPort(message->dest_port());
   if (index < 0) {
-    delete message;
     return false;
   }
   ASSERT(index >= 0);
@@ -248,7 +248,7 @@
   MessageHandler* handler = map_[index].handler;
   ASSERT(map_[index].port != 0);
   ASSERT((handler != NULL) && (handler != deleted_entry_));
-  handler->PostMessage(message, before_events);
+  handler->PostMessage(std::move(message), before_events);
   return true;
 }
 
diff --git a/runtime/vm/port.h b/runtime/vm/port.h
index d1afa2c..155e3832 100644
--- a/runtime/vm/port.h
+++ b/runtime/vm/port.h
@@ -5,6 +5,8 @@
 #ifndef RUNTIME_VM_PORT_H_
 #define RUNTIME_VM_PORT_H_
 
+#include <memory>
+
 #include "include/dart_api.h"
 #include "vm/allocation.h"
 #include "vm/globals.h"
@@ -46,7 +48,8 @@
   // active any longer.
   //
   // Claims ownership of 'message'.
-  static bool PostMessage(Message* message, bool before_events = false);
+  static bool PostMessage(std::unique_ptr<Message> message,
+                          bool before_events = false);
 
   // Returns whether a port is local to the current isolate.
   static bool IsLocalPort(Dart_Port id);
diff --git a/runtime/vm/port_test.cc b/runtime/vm/port_test.cc
index ac65fd9..6526471 100644
--- a/runtime/vm/port_test.cc
+++ b/runtime/vm/port_test.cc
@@ -35,7 +35,7 @@
 
   void MessageNotify(Message::Priority priority) { notify_count++; }
 
-  MessageStatus HandleMessage(Message* message) { return kOK; }
+  MessageStatus HandleMessage(std::unique_ptr<Message> message) { return kOK; }
 
   int notify_count;
 };
@@ -133,8 +133,8 @@
   intptr_t message_len = strlen(message) + 1;
 
   EXPECT(PortMap::PostMessage(
-      new Message(port, reinterpret_cast<uint8_t*>(strdup(message)),
-                  message_len, NULL, Message::kNormalPriority)));
+      Message::New(port, reinterpret_cast<uint8_t*>(strdup(message)),
+                   message_len, nullptr, Message::kNormalPriority)));
 
   // Check that the message notify callback was called.
   EXPECT_EQ(1, handler.notify_count);
@@ -147,7 +147,7 @@
   EXPECT_EQ(0, handler.notify_count);
 
   EXPECT(PortMap::PostMessage(
-      new Message(port, Smi::New(42), Message::kNormalPriority)));
+      Message::New(port, Smi::New(42), Message::kNormalPriority)));
 
   // Check that the message notify callback was called.
   EXPECT_EQ(1, handler.notify_count);
@@ -160,7 +160,7 @@
   EXPECT_EQ(0, handler.notify_count);
 
   EXPECT(PortMap::PostMessage(
-      new Message(port, Object::null(), Message::kNormalPriority)));
+      Message::New(port, Object::null(), Message::kNormalPriority)));
 
   // Check that the message notify callback was called.
   EXPECT_EQ(1, handler.notify_count);
@@ -177,8 +177,8 @@
   intptr_t message_len = strlen(message) + 1;
 
   EXPECT(!PortMap::PostMessage(
-      new Message(port, reinterpret_cast<uint8_t*>(strdup(message)),
-                  message_len, NULL, Message::kNormalPriority)));
+      Message::New(port, reinterpret_cast<uint8_t*>(strdup(message)),
+                   message_len, nullptr, Message::kNormalPriority)));
 }
 
 }  // namespace dart
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index aeb614e..736277a 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -35,7 +35,7 @@
     free(_msg);
   }
 
-  MessageStatus HandleMessage(Message* message) {
+  MessageStatus HandleMessage(std::unique_ptr<Message> message) {
     if (_msg != NULL) {
       free(_msg);
       _msg = NULL;
@@ -47,7 +47,7 @@
       response_obj = message->raw_obj();
     } else {
       Thread* thread = Thread::Current();
-      MessageSnapshotReader reader(message, thread);
+      MessageSnapshotReader reader(message.get(), thread);
       response_obj = reader.ReadObject();
     }
     if (response_obj.IsString()) {
@@ -64,8 +64,6 @@
       _msg = strdup(reinterpret_cast<char*>(response.DataAddr(0)));
     }
 
-    delete message;
-
     return kOK;
   }
 
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 3ad2984..aeb1714 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -1461,9 +1461,10 @@
   delete finalizable_data_;
 }
 
-Message* MessageWriter::WriteMessage(const Object& obj,
-                                     Dart_Port dest_port,
-                                     Message::Priority priority) {
+std::unique_ptr<Message> MessageWriter::WriteMessage(
+    const Object& obj,
+    Dart_Port dest_port,
+    Message::Priority priority) {
   ASSERT(kind() == Snapshot::kMessage);
   ASSERT(isolate() != NULL);
 
@@ -1486,8 +1487,8 @@
 
   MessageFinalizableData* finalizable_data = finalizable_data_;
   finalizable_data_ = NULL;
-  return new Message(dest_port, buffer(), BytesWritten(), finalizable_data,
-                     priority);
+  return Message::New(dest_port, buffer(), BytesWritten(), finalizable_data,
+                      priority);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index e4861cb..995afc7 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -728,22 +728,17 @@
 
 class SerializedObjectBuffer : public StackResource {
  public:
-  SerializedObjectBuffer() : StackResource(Thread::Current()), message_(NULL) {}
+  SerializedObjectBuffer()
+      : StackResource(Thread::Current()), message_(nullptr) {}
 
-  virtual ~SerializedObjectBuffer() { delete message_; }
-
-  void set_message(Message* message) {
-    ASSERT(message_ == NULL);
-    message_ = message;
+  void set_message(std::unique_ptr<Message> message) {
+    ASSERT(message_ == nullptr);
+    message_ = std::move(message);
   }
-  Message* StealMessage() {
-    Message* result = message_;
-    message_ = NULL;
-    return result;
-  }
+  std::unique_ptr<Message> StealMessage() { return std::move(message_); }
 
  private:
-  Message* message_;
+  std::unique_ptr<Message> message_;
 };
 
 class MessageWriter : public SnapshotWriter {
@@ -752,9 +747,9 @@
   explicit MessageWriter(bool can_send_any_object);
   ~MessageWriter();
 
-  Message* WriteMessage(const Object& obj,
-                        Dart_Port dest_port,
-                        Message::Priority priority);
+  std::unique_ptr<Message> WriteMessage(const Object& obj,
+                                        Dart_Port dest_port,
+                                        Message::Priority priority);
 
   MessageFinalizableData* finalizable_data() const { return finalizable_data_; }
 
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index d11d4213..e05f475 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -115,12 +115,11 @@
 static void CheckEncodeDecodeMessage(Dart_CObject* root) {
   // Encode and decode the message.
   ApiMessageWriter writer;
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteCMessage(root, ILLEGAL_PORT, Message::kNormalPriority);
 
-  ApiMessageReader api_reader(message);
+  ApiMessageReader api_reader(message.get());
   Dart_CObject* new_root = api_reader.ReadMessage();
-  delete message;
 
   // Check that the two messages are the same.
   CompareDartCObjects(root, new_root);
@@ -128,9 +127,9 @@
 
 static void ExpectEncodeFail(Dart_CObject* root) {
   ApiMessageWriter writer;
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteCMessage(root, ILLEGAL_PORT, Message::kNormalPriority);
-  EXPECT(message == NULL);
+  EXPECT(message == nullptr);
 }
 
 ISOLATE_UNIT_TEST_CASE(SerializeNull) {
@@ -139,23 +138,21 @@
   // Write snapshot with object content.
   const Object& null_object = Object::Handle();
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(null_object, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   Dart_CObject* root = api_reader.ReadMessage();
   EXPECT_NOTNULL(root);
   EXPECT_EQ(Dart_CObject_kNull, root->type);
   CheckEncodeDecodeMessage(root);
-
-  delete message;
 }
 
 ISOLATE_UNIT_TEST_CASE(SerializeSmi1) {
@@ -164,24 +161,22 @@
   // Write snapshot with object content.
   const Smi& smi = Smi::Handle(Smi::New(124));
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(smi, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   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;
 }
 
 ISOLATE_UNIT_TEST_CASE(SerializeSmi2) {
@@ -190,30 +185,28 @@
   // Write snapshot with object content.
   const Smi& smi = Smi::Handle(Smi::New(-1));
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(smi, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   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.
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(mint, ILLEGAL_PORT, Message::kNormalPriority);
 
   {
@@ -221,17 +214,16 @@
     Thread* thread = Thread::Current();
     StackZone zone(thread);
     // Read object back from the snapshot.
-    MessageSnapshotReader reader(message, thread);
+    MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   Dart_CObject* root = api_reader.ReadMessage();
   EXPECT_NOTNULL(root);
   CheckEncodeDecodeMessage(root);
-  delete message;
   return root;
 }
 
@@ -285,24 +277,22 @@
   // Write snapshot with object content.
   const Double& dbl = Double::Handle(Double::New(101.29));
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(dbl, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   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;
 }
 
 ISOLATE_UNIT_TEST_CASE(SerializeTrue) {
@@ -311,11 +301,11 @@
   // Write snapshot with true object.
   const Bool& bl = Bool::True();
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(bl, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), thread);
   const Object& serialized_object = Object::Handle(reader.ReadObject());
   fprintf(stderr, "%s / %s\n", bl.ToCString(), serialized_object.ToCString());
 
@@ -323,14 +313,12 @@
 
   // Read object back from the snapshot into a C structure.
   ApiNativeScope scope;
-  ApiMessageReader api_reader(message);
+  ApiMessageReader api_reader(message.get());
   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;
 }
 
 ISOLATE_UNIT_TEST_CASE(SerializeFalse) {
@@ -339,35 +327,33 @@
   // Write snapshot with false object.
   const Bool& bl = Bool::False();
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(bl, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   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;
 }
 
 ISOLATE_UNIT_TEST_CASE(SerializeCapability) {
   // Write snapshot with object content.
   const Capability& capability = Capability::Handle(Capability::New(12345));
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(capability, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), thread);
   Capability& obj = Capability::Handle();
   obj ^= reader.ReadObject();
 
@@ -375,24 +361,22 @@
 
   // Read object back from the snapshot into a C structure.
   ApiNativeScope scope;
-  ApiMessageReader api_reader(message);
+  ApiMessageReader api_reader(message.get());
   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;
 }
 
 #define TEST_ROUND_TRIP_IDENTICAL(object)                                      \
   {                                                                            \
     MessageWriter writer(true);                                                \
-    Message* message = writer.WriteMessage(                                    \
+    std::unique_ptr<Message> message = writer.WriteMessage(                    \
         Object::Handle(object), ILLEGAL_PORT, Message::kNormalPriority);       \
-    MessageSnapshotReader reader(message, thread);                             \
+    MessageSnapshotReader reader(message.get(), thread);                       \
     EXPECT(reader.ReadObject() == object);                                     \
-    delete message;                                                            \
   }
 
 ISOLATE_UNIT_TEST_CASE(SerializeSingletons) {
@@ -417,23 +401,22 @@
   // Write snapshot with object content.
   String& str = String::Handle(String::New(cstr));
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(str, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   Dart_CObject* root = api_reader.ReadMessage();
   EXPECT_EQ(Dart_CObject_kString, root->type);
   EXPECT_STREQ(cstr, root->value.as_string);
   CheckEncodeDecodeMessage(root);
-  delete message;
 }
 
 ISOLATE_UNIT_TEST_CASE(SerializeString) {
@@ -461,18 +444,18 @@
     array.SetAt(i, smi);
   }
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   Dart_CObject* root = api_reader.ReadMessage();
   EXPECT_EQ(Dart_CObject_kArray, root->type);
   EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -482,8 +465,6 @@
     EXPECT_EQ(i, element->value.as_int32);
   }
   CheckEncodeDecodeMessage(root);
-
-  delete message;
 }
 
 ISOLATE_UNIT_TEST_CASE(SerializeArrayWithTypeArgument) {
@@ -498,18 +479,18 @@
     array.SetAt(i, smi);
   }
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   Dart_CObject* root = api_reader.ReadMessage();
   EXPECT_EQ(Dart_CObject_kArray, root->type);
   EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -519,8 +500,6 @@
     EXPECT_EQ(i, element->value.as_int32);
   }
   CheckEncodeDecodeMessage(root);
-
-  delete message;
 }
 
 TEST_CASE(FailSerializeLargeArray) {
@@ -575,25 +554,23 @@
   const int kArrayLength = 0;
   Array& array = Array::Handle(Array::New(kArrayLength));
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   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;
 }
 
 ISOLATE_UNIT_TEST_CASE(SerializeByteArray) {
@@ -605,18 +582,18 @@
     typed_data.SetUint8(i, i);
   }
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(typed_data, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   Dart_CObject* root = api_reader.ReadMessage();
   EXPECT_EQ(Dart_CObject_kTypedData, root->type);
   EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length);
@@ -624,8 +601,6 @@
     EXPECT(root->value.as_typed_data.values[i] == i);
   }
   CheckEncodeDecodeMessage(root);
-
-  delete message;
 }
 
 #define TEST_TYPED_ARRAY(darttype, ctype)                                      \
@@ -639,16 +614,15 @@
       array.Set##darttype((i * scale), i);                                     \
     }                                                                          \
     MessageWriter writer(true);                                                \
-    Message* message =                                                         \
+    std::unique_ptr<Message> message =                                         \
         writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority);    \
-    MessageSnapshotReader reader(message, thread);                             \
+    MessageSnapshotReader reader(message.get(), thread);                       \
     TypedData& serialized_array = TypedData::Handle();                         \
     serialized_array ^= reader.ReadObject();                                   \
     for (int i = 0; i < kArrayLength; i++) {                                   \
       EXPECT_EQ(static_cast<ctype>(i),                                         \
                 serialized_array.Get##darttype(i* scale));                     \
     }                                                                          \
-    delete message;                                                            \
   }
 
 #define TEST_EXTERNAL_TYPED_ARRAY(darttype, ctype)                             \
@@ -661,16 +635,15 @@
                                reinterpret_cast<uint8_t*>(data), length));     \
     intptr_t scale = array.ElementSizeInBytes();                               \
     MessageWriter writer(true);                                                \
-    Message* message =                                                         \
+    std::unique_ptr<Message> message =                                         \
         writer.WriteMessage(array, ILLEGAL_PORT, Message::kNormalPriority);    \
-    MessageSnapshotReader reader(message, thread);                             \
+    MessageSnapshotReader reader(message.get(), thread);                       \
     ExternalTypedData& serialized_array = ExternalTypedData::Handle();         \
     serialized_array ^= reader.ReadObject();                                   \
     for (int i = 0; i < length; i++) {                                         \
       EXPECT_EQ(static_cast<ctype>(data[i]),                                   \
                 serialized_array.Get##darttype(i* scale));                     \
     }                                                                          \
-    delete message;                                                            \
   }
 
 ISOLATE_UNIT_TEST_CASE(SerializeTypedArray) {
@@ -705,26 +678,24 @@
   TypedData& typed_data = TypedData::Handle(
       TypedData::New(kTypedDataUint8ArrayCid, kTypedDataLength));
   MessageWriter writer(true);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(typed_data, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot.
-  MessageSnapshotReader reader(message, thread);
+  MessageSnapshotReader reader(message.get(), 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(message);
+  ApiMessageReader api_reader(message.get());
   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;
 }
 
 VM_UNIT_TEST_CASE(FullSnapshot) {
@@ -805,7 +776,8 @@
 }
 
 // Helper function to call a top level Dart function and serialize the result.
-static Message* GetSerialized(Dart_Handle lib, const char* dart_function) {
+static std::unique_ptr<Message> GetSerialized(Dart_Handle lib,
+                                              const char* dart_function) {
   Dart_Handle result;
   {
     TransitionVMToNative transition(Thread::Current());
@@ -831,19 +803,17 @@
   String& str = String::Handle();
   str ^= Api::UnwrapHandle(dart_string);
   MessageWriter writer(false);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(str, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot into a C structure.
   ApiNativeScope scope;
-  ApiMessageReader api_reader(message);
+  ApiMessageReader api_reader(message.get());
   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) {
@@ -851,17 +821,15 @@
   String& str = String::Handle();
   str ^= Api::UnwrapHandle(dart_string);
   MessageWriter writer(false);
-  Message* message =
+  std::unique_ptr<Message> message =
       writer.WriteMessage(str, ILLEGAL_PORT, Message::kNormalPriority);
 
   // Read object back from the snapshot into a C structure.
   ApiNativeScope scope;
-  ApiMessageReader api_reader(message);
+  ApiMessageReader api_reader(message.get());
   Dart_CObject* root = api_reader.ReadMessage();
   EXPECT_NOTNULL(root);
   EXPECT_EQ(Dart_CObject_kUnsupported, root->type);
-
-  delete message;
 }
 
 VM_UNIT_TEST_CASE(DartGeneratedMessages) {
@@ -958,18 +926,17 @@
       Smi& smi = Smi::Handle();
       smi ^= Api::UnwrapHandle(smi_result);
       MessageWriter writer(false);
-      Message* message =
+      std::unique_ptr<Message> message =
           writer.WriteMessage(smi, ILLEGAL_PORT, Message::kNormalPriority);
 
       // Read object back from the snapshot into a C structure.
       ApiNativeScope scope;
-      ApiMessageReader api_reader(message);
+      ApiMessageReader api_reader(message.get());
       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;
     }
     CheckString(ascii_string_result, "Hello, world!");
     CheckString(non_ascii_string_result, "Blåbærgrød");
@@ -1028,9 +995,9 @@
     StackZone zone(thread);
     {
       // Generate a list of nulls from Dart code.
-      Message* message = GetSerialized(lib, "getList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1038,13 +1005,12 @@
         EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type);
       }
       CheckEncodeDecodeMessage(root);
-      delete message;
     }
     {
       // Generate a list of ints from Dart code.
-      Message* message = GetSerialized(lib, "getIntList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getIntList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1053,13 +1019,12 @@
         EXPECT_EQ(i, root->value.as_array.values[i]->value.as_int32);
       }
       CheckEncodeDecodeMessage(root);
-      delete message;
     }
     {
       // Generate a list of strings from Dart code.
-      Message* message = GetSerialized(lib, "getStringList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1069,13 +1034,12 @@
         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.
-      Message* message = GetSerialized(lib, "getMixedList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1094,7 +1058,6 @@
           EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type);
         }
       }
-      delete message;
     }
   }
   Dart_ExitScope();
@@ -1156,9 +1119,9 @@
     StackZone zone(thread);
     {
       // Generate a list of nulls from Dart code.
-      Message* message = GetSerialized(lib, "getList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1166,13 +1129,12 @@
         EXPECT_EQ(Dart_CObject_kNull, root->value.as_array.values[i]->type);
       }
       CheckEncodeDecodeMessage(root);
-      delete message;
     }
     {
       // Generate a list of ints from Dart code.
-      Message* message = GetSerialized(lib, "getIntList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getIntList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1181,13 +1143,12 @@
         EXPECT_EQ(i, root->value.as_array.values[i]->value.as_int32);
       }
       CheckEncodeDecodeMessage(root);
-      delete message;
     }
     {
       // Generate a list of strings from Dart code.
-      Message* message = GetSerialized(lib, "getStringList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1197,13 +1158,12 @@
         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.
-      Message* message = GetSerialized(lib, "getListList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getListList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1217,13 +1177,12 @@
           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.
-      Message* message = GetSerialized(lib, "getMixedList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1319,7 +1278,6 @@
         EXPECT_EQ(Dart_CObject_kInt32, e->type);
         EXPECT_EQ(i + 1, e->value.as_int32);
       }
-      delete message;
     }
   }
   Dart_ExitScope();
@@ -1394,9 +1352,9 @@
     StackZone zone(thread);
     {
       // Generate a list of strings from Dart code.
-      Message* message = GetSerialized(lib, "getStringList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1406,13 +1364,12 @@
         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.
-      Message* message = GetSerialized(lib, "getMintList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getMintList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1422,13 +1379,12 @@
         EXPECT_EQ(Dart_CObject_kInt64, element->type);
         EXPECT_EQ(DART_INT64_C(0x7FFFFFFFFFFFFFFF), element->value.as_int64);
       }
-      delete message;
     }
     {
       // Generate a list of doubles from Dart code.
-      Message* message = GetSerialized(lib, "getDoubleList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getDoubleList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1442,13 +1398,12 @@
         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.
-      Message* message = GetSerialized(lib, "getTypedDataList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getTypedDataList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1459,13 +1414,13 @@
         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.
-      Message* message = GetSerialized(lib, "getTypedDataViewList");
+      std::unique_ptr<Message> message =
+          GetSerialized(lib, "getTypedDataViewList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1478,13 +1433,12 @@
         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.
-      Message* message = GetSerialized(lib, "getMixedList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1507,13 +1461,12 @@
           EXPECT_STREQ(2.72, element->value.as_double);
         }
       }
-      delete message;
     }
     {
       // Generate a list of objects of different types from Dart code.
-      Message* message = GetSerialized(lib, "getSelfRefList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getSelfRefList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1522,7 +1475,6 @@
         EXPECT_EQ(Dart_CObject_kArray, element->type);
         EXPECT_EQ(root, element);
       }
-      delete message;
     }
   }
   Dart_ExitScope();
@@ -1603,9 +1555,9 @@
     StackZone zone(thread);
     {
       // Generate a list of strings from Dart code.
-      Message* message = GetSerialized(lib, "getStringList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getStringList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1615,13 +1567,12 @@
         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.
-      Message* message = GetSerialized(lib, "getMintList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getMintList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1631,13 +1582,12 @@
         EXPECT_EQ(Dart_CObject_kInt64, element->type);
         EXPECT_EQ(DART_INT64_C(0x7FFFFFFFFFFFFFFF), element->value.as_int64);
       }
-      delete message;
     }
     {
       // Generate a list of doubles from Dart code.
-      Message* message = GetSerialized(lib, "getDoubleList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getDoubleList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1652,13 +1602,12 @@
         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.
-      Message* message = GetSerialized(lib, "getTypedDataList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getTypedDataList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1669,13 +1618,13 @@
         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.
-      Message* message = GetSerialized(lib, "getTypedDataViewList");
+      std::unique_ptr<Message> message =
+          GetSerialized(lib, "getTypedDataViewList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1688,13 +1637,12 @@
         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.
-      Message* message = GetSerialized(lib, "getMixedList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getMixedList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1717,13 +1665,12 @@
           EXPECT_STREQ(2.72, element->value.as_double);
         }
       }
-      delete message;
     }
     {
       // Generate a list of objects of different types from Dart code.
-      Message* message = GetSerialized(lib, "getSelfRefList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getSelfRefList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       EXPECT_EQ(kArrayLength, root->value.as_array.length);
@@ -1732,7 +1679,6 @@
         EXPECT_EQ(Dart_CObject_kArray, element->type);
         EXPECT_EQ(root, element);
       }
-      delete message;
     }
   }
   Dart_ExitScope();
@@ -1834,9 +1780,9 @@
     StackZone zone(thread);
     {
       // Generate a list of Uint8Lists from Dart code.
-      Message* message = GetSerialized(lib, "getTypedDataList");
+      std::unique_ptr<Message> message = GetSerialized(lib, "getTypedDataList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       struct {
@@ -1857,13 +1803,13 @@
         i++;
       }
       EXPECT_EQ(i, root->value.as_array.length);
-      delete message;
     }
     {
       // Generate a list of Uint8List views from Dart code.
-      Message* message = GetSerialized(lib, "getTypedDataViewList");
+      std::unique_ptr<Message> message =
+          GetSerialized(lib, "getTypedDataViewList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       struct {
@@ -1897,13 +1843,13 @@
         i++;
       }
       EXPECT_EQ(i, root->value.as_array.length);
-      delete message;
     }
     {
       // Generate a list of Uint8Lists from Dart code.
-      Message* message = GetSerialized(lib, "getMultipleTypedDataViewList");
+      std::unique_ptr<Message> message =
+          GetSerialized(lib, "getMultipleTypedDataViewList");
       ApiNativeScope scope;
-      Dart_CObject* root = GetDeserialized(message);
+      Dart_CObject* root = GetDeserialized(message.get());
       EXPECT_NOTNULL(root);
       EXPECT_EQ(Dart_CObject_kArray, root->type);
       struct {
@@ -1928,7 +1874,6 @@
         i++;
       }
       EXPECT_EQ(i, root->value.as_array.length);
-      delete message;
     }
   }
   Dart_ExitScope();