Reland "Reland "Reland "Mojo C++ Bindings: Dynamic message allocation"""

This is a reland of 41830fd00c5d24392e7487c1db158040171e2f5e

Because we must go deeper. (MSan complaints fixed for-realsies.)

Original change's description:
> Reland "Reland "Mojo C++ Bindings: Dynamic message allocation""
> 
> This is a reland of 9ea314373dcd35d1a7a2dc48627d18831d6e789f
> Original change's description:
> > Reland "Mojo C++ Bindings: Dynamic message allocation"
> > 
> > This is a reland of 0463c3dc61221f43758bb30f9a4e88b4e1e80fe0
> > 
> > Breakage was caused by a defunct test. Test has been deleted.
> > 
> > Original change's description:
> > > Mojo C++ Bindings: Dynamic message allocation
> > > 
> > > Reduces the "prepare-to-serialize" bindings step to handle and
> > > interface collection instead of full message size measurement.
> > > 
> > > Allows the serialized message buffer to be expanded dynamically
> > > during serialization, and reworks the serialization code to support
> > > writing into a buffer which may be reallocated (and thus relocated)
> > > between operations.
> > > 
> > > Bug: 742369
> > > Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
> > > Change-Id: I5cacee48343f565d68a77455872b0bf4e74e7674
> > > 
> > > [email protected]
> > > 
> > > Change-Id: I5cacee48343f565d68a77455872b0bf4e74e7674
> > > Reviewed-on: https://chromium-review.googlesource.com/580568
> > > Commit-Queue: Ken Rockot <[email protected]>
> > > Reviewed-by: Yuzhu Shen <[email protected]>
> > > Cr-Commit-Position: refs/heads/master@{#489210}
> > 
> > Bug: 742369
> > Change-Id: Ic3a55bae2977fdeec93fbeddd95b04dc6aabe880
> > Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
> > 
> > [email protected]
> > [email protected]
> > 
> > Change-Id: Ic3a55bae2977fdeec93fbeddd95b04dc6aabe880
> > Reviewed-on: https://chromium-review.googlesource.com/584038
> > Commit-Queue: Ken Rockot <[email protected]>
> > Reviewed-by: Ken Rockot <[email protected]>
> > Cr-Commit-Position: refs/heads/master@{#489326}
> 
> Bug: 742369
> Change-Id: Ief594662ed6d04c51eef8bbd72db291a9cdbf4a9
> Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
> 
> [email protected]
> [email protected]
> 
> Change-Id: Ief594662ed6d04c51eef8bbd72db291a9cdbf4a9
> Reviewed-on: https://chromium-review.googlesource.com/587047
> Reviewed-by: Ken Rockot <[email protected]>
> Commit-Queue: Ken Rockot <[email protected]>
> Cr-Commit-Position: refs/heads/master@{#489828}

Bug: 742369
Change-Id: I9ec1abe53a0973ab651ec53cbdd3c80b1bb9f801
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel

[email protected]
[email protected]

Change-Id: I9ec1abe53a0973ab651ec53cbdd3c80b1bb9f801
Reviewed-on: https://chromium-review.googlesource.com/590649
Commit-Queue: Ken Rockot <[email protected]>
Reviewed-by: Ken Rockot <[email protected]>
Cr-Commit-Position: refs/heads/master@{#490340}
diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc
index 11b02d9fb..9dbebed 100644
--- a/mojo/public/cpp/bindings/lib/message.cc
+++ b/mojo/public/cpp/bindings/lib/message.cc
@@ -37,7 +37,7 @@
 
 template <typename HeaderType>
 void AllocateHeaderFromBuffer(internal::Buffer* buffer, HeaderType** header) {
-  *header = static_cast<HeaderType*>(buffer->Allocate(sizeof(HeaderType)));
+  *header = buffer->AllocateAndGet<HeaderType>();
   (*header)->num_bytes = sizeof(HeaderType);
 }
 
@@ -102,7 +102,7 @@
       ignore_result(handles->at(i).release());
   }
 
-  internal::Buffer payload_buffer(buffer, buffer_size);
+  internal::Buffer payload_buffer(handle.get(), buffer, buffer_size);
 
   // Make sure we zero the memory first!
   memset(payload_buffer.data(), 0, total_size);
@@ -136,7 +136,7 @@
   if (rv != MOJO_RESULT_OK)
     return;
 
-  internal::Buffer payload_buffer(buffer, num_bytes);
+  internal::Buffer payload_buffer(MessageHandle(message), buffer, buffer_size);
   WriteMessageHeader(context->message_name(), context->message_flags(),
                      0 /* payload_interface_id_count */, &payload_buffer);
 
@@ -153,6 +153,7 @@
   }
 
   context->SerializePayload(&payload_buffer);
+  payload_buffer.Seal();
 }
 
 void DestroyUnserializedContext(uintptr_t context) {
@@ -190,8 +191,6 @@
   CreateSerializedMessageObject(name, flags, payload_size,
                                 payload_interface_id_count, handles, &handle_,
                                 &payload_buffer_);
-  data_ = payload_buffer_.data();
-  data_size_ = payload_buffer_.size();
   transferable_ = true;
   serialized_ = true;
 }
@@ -227,8 +226,7 @@
       return;
     }
 
-    data_ = buffer;
-    data_size_ = num_bytes;
+    payload_buffer_ = internal::Buffer(buffer, num_bytes, num_bytes);
     serialized_ = true;
   } else {
     DCHECK_EQ(MOJO_RESULT_OK, get_context_result);
@@ -238,8 +236,9 @@
     // choice is V1 reflects unserialized message capabilities: we may or may
     // not need to support request IDs (which require at least V1), but we never
     // (for now, anyway) need to support associated interface handles (V2).
-    data_ = context->header();
-    data_size_ = sizeof(internal::MessageHeaderV1);
+    payload_buffer_ =
+        internal::Buffer(context->header(), sizeof(internal::MessageHeaderV1),
+                         sizeof(internal::MessageHeaderV1));
     transferable_ = true;
     serialized_ = false;
   }
@@ -253,10 +252,9 @@
 
 void Message::Reset() {
   handle_.reset();
+  payload_buffer_.Reset();
   handles_.clear();
   associated_endpoint_handles_.clear();
-  data_ = nullptr;
-  data_size_ = 0;
   transferable_ = false;
   serialized_ = false;
 }
@@ -284,7 +282,7 @@
     DCHECK_GE(payload_end, payload_begin);
     num_bytes = payload_end - payload_begin;
   }
-  DCHECK_LE(num_bytes, std::numeric_limits<uint32_t>::max());
+  DCHECK(base::IsValueInRangeForNumericType<uint32_t>(num_bytes));
   return static_cast<uint32_t>(num_bytes);
 }
 
@@ -305,6 +303,7 @@
   // SerializeAssociatedEndpointHandles() must be called before this method.
   DCHECK(associated_endpoint_handles_.empty());
   DCHECK(transferable_);
+  payload_buffer_.Seal();
   auto handle = std::move(handle_);
   Reset();
   return handle;
@@ -323,16 +322,19 @@
   DCHECK_GE(version(), 2u);
   DCHECK(header_v2()->payload_interface_ids.is_null());
   DCHECK(payload_buffer_.is_valid());
+  DCHECK(handle_.is_valid());
 
   size_t size = associated_endpoint_handles_.size();
-  auto* data = internal::Array_Data<uint32_t>::New(size, &payload_buffer_);
-  header_v2()->payload_interface_ids.Set(data);
+
+  internal::Array_Data<uint32_t>::BufferWriter handle_writer;
+  handle_writer.Allocate(size, &payload_buffer_);
+  header_v2()->payload_interface_ids.Set(handle_writer.data());
 
   for (size_t i = 0; i < size; ++i) {
     ScopedInterfaceEndpointHandle& handle = associated_endpoint_handles_[i];
 
     DCHECK(handle.pending_association());
-    data->storage()[i] =
+    handle_writer->storage()[i] =
         group_controller->AssociateInterface(std::move(handle));
   }
   associated_endpoint_handles_.clear();